Compare commits

...

4 Commits

Author SHA1 Message Date
Juhani Krekelä 254ac20186 Run a REPL if no arguments are given 2023-06-01 19:39:48 +03:00
Juhani Krekelä e8e81b4564 Add support for cubic yards 2023-06-01 19:31:55 +03:00
Juhani Krekelä 8e4680a3bc Add support for square yards 2023-06-01 19:24:11 +03:00
Juhani Krekelä b8d9ba177c Add a caveat section in the README.md 2023-06-01 19:17:20 +03:00
6 changed files with 115 additions and 21 deletions

View File

@ -16,7 +16,7 @@ together if the units are compatible:
metrify 1 acre 15 square feet
You can also invoke metrify without arguments, in which case it will give you a
prompt to type the expression into.
prompt to type the expression into. Press ^D to exit.
Result display
--------------
@ -57,6 +57,7 @@ Supported units
* square inch (in²)
* square foot (ft²)
* square yard (yd²)
* acre (ac)
* square mile (mi²)
@ -64,6 +65,7 @@ Supported units
* cubic inch (in³)
* cubic foot (ft³)
* cubic yard (yd³)
### Imperial fluid volume units
@ -90,6 +92,12 @@ metrify you do not need to explicitly tell it the unit you are converting to,
because due to its requirements (conversion is always from non-metric to metric)
it can automatically pick the correct one.
Why should I use units(1) instead of metrify?
---------------------------------------------
units(1) includes many more units than covered by metrify, in addition to
allowing other conversions than non-metric to metric. It can also be used for
calculations involving units, which metrify does not handle outside of addition.
Building and installation
-------------------------
You can build and test out metrify with `cargo run`. If you want to install it

View File

@ -91,6 +91,11 @@ fn get_conversion(unit: NonMetric) -> Conversion {
from: inch_from * inch_from,
to: MetricQuantity { amount: 12.0 * inch_to * 12.0 * inch_to, unit: Metric::SquareMetre },
},
NonMetric::SquareYard => Conversion {
offset: 0.0,
from: inch_from * inch_from,
to: MetricQuantity { amount: 3.0 * 12.0 * inch_to * 3.0 * 12.0 * inch_to, unit: Metric::SquareMetre },
},
NonMetric::Acre => Conversion {
offset: 0.0,
from: inch_from * inch_from,
@ -112,6 +117,11 @@ fn get_conversion(unit: NonMetric) -> Conversion {
from: inch_from * inch_from * inch_from,
to: MetricQuantity { amount: 12.0 * inch_to * 12.0 * inch_to * 12.0 * inch_to, unit: Metric::CubicMetre },
},
NonMetric::CubicYard => Conversion {
offset: 0.0,
from: inch_from * inch_from * inch_from,
to: MetricQuantity { amount: 3.0 * 12.0 * inch_to * 3.0 * 12.0 * inch_to * 3.0 * 12.0 * inch_to, unit: Metric::CubicMetre },
},
// Fluid volume
NonMetric::ImperialFluidOunce => Conversion {
offset: 0.0,
@ -223,6 +233,7 @@ mod test {
let tests = [
Test(NonMetric::SquareInch, 0.00064516),
Test(NonMetric::SquareFoot, 0.09290304),
Test(NonMetric::SquareYard, 0.83612736),
Test(NonMetric::Acre, 4046.8564224),
Test(NonMetric::SquareMile, 2589988.110336),
];
@ -234,6 +245,7 @@ mod test {
let tests = [
Test(NonMetric::CubicInch, 1.6387064e-5),
Test(NonMetric::CubicFoot, 0.028316846592),
Test(NonMetric::CubicYard, 0.764554857984),
];
run_tests(&tests, Metric::CubicMetre);
}

View File

@ -84,11 +84,13 @@ fn unit_to_name(unit: NonMetric) -> &'static str {
// Area
NonMetric::SquareInch => "square inches",
NonMetric::SquareFoot => "square feet",
NonMetric::SquareYard => "square yards",
NonMetric::Acre => "acres",
NonMetric::SquareMile => "square miles",
// Volume
NonMetric::CubicInch => "cubic inches",
NonMetric::CubicFoot => "cubic feet",
NonMetric::CubicYard => "cubic yards",
// Fluid volume
NonMetric::ImperialFluidOunce => "imperial fluid ounces",
NonMetric::ImperialPint => "imperial pints",
@ -140,11 +142,13 @@ mod test {
// Area
assert_eq!(run("1 in²"), Ok("6.452 cm²".to_string()));
assert_eq!(run("1 ft²"), Ok("929 cm²".to_string()));
assert_eq!(run("1 yd²"), Ok("8 361 cm²".to_string()));
assert_eq!(run("1 acre"), Ok("4 047 m²".to_string()));
assert_eq!(run("1 mi²"), Ok("2.59 km²".to_string()));
// Volume
assert_eq!(run("1 in³"), Ok("16.39 cm³".to_string()));
assert_eq!(run("1 ft³"), Ok("28 317 cm³".to_string()));
assert_eq!(run("1 yd³"), Ok("764 555 cm³".to_string()));
// Fluid volume
assert_eq!(run("1 imp fl oz"), Ok("2.841 cl".to_string()));
assert_eq!(run("1 imp pt"), Ok("5.683 dl".to_string()));

View File

@ -9,31 +9,43 @@ fn main() {
let name = args[0].clone();
let args = args[1..].join(" ");
let mut input = args;
if input.len() == 0 {
print!("> ");
match io::stdout().flush() {
Ok(_) => {}
if args.len() == 0 {
loop {
print!("> ");
match io::stdout().flush() {
Ok(_) => {}
Err(err) => {
eprintln!("{name}: Error: {err}");
process::exit(1);
}
}
let mut input = String::new();
match io::stdin().read_line(&mut input) {
Ok(_) => {}
Err(err) => {
eprintln!("{name}: Error: {err}");
process::exit(1);
}
}
if input.len() == 0 {
println!(); // Add a newline if user pressed ^D
break;
}
match run(&input) {
Ok(str) => println!("{str}"),
Err(err) => {
eprintln!("Error: {err}");
}
}
}
} else {
match run(&args) {
Ok(str) => println!("{str}"),
Err(err) => {
eprintln!("{name}: Error: {err}");
process::exit(1);
}
}
match io::stdin().read_line(&mut input) {
Ok(_) => {}
Err(err) => {
eprintln!("{name}: Error: {err}");
process::exit(1);
}
}
}
match run(&input) {
Ok(str) => println!("{str}"),
Err(err) => {
eprintln!("{name}: Error: {err}");
process::exit(1);
}
}
}

View File

@ -156,6 +156,19 @@ fn parse_unit(input: String) -> Result<NonMetric, ParseError> {
"'^2" => Ok(NonMetric::SquareFoot),
"sf" => Ok(NonMetric::SquareFoot),
"square yard" => Ok(NonMetric::SquareYard),
"square yards" => Ok(NonMetric::SquareYard),
"square yd" => Ok(NonMetric::SquareYard),
"sq yard" => Ok(NonMetric::SquareYard),
"sq yards" => Ok(NonMetric::SquareYard),
"sq yd" => Ok(NonMetric::SquareYard),
"yard²" => Ok(NonMetric::SquareYard),
"yards²" => Ok(NonMetric::SquareYard),
"yd²" => Ok(NonMetric::SquareYard),
"yard^2" => Ok(NonMetric::SquareYard),
"yards^2" => Ok(NonMetric::SquareYard),
"yd^2" => Ok(NonMetric::SquareYard),
"acre" => Ok(NonMetric::Acre),
"acres" => Ok(NonMetric::Acre),
"ac" => Ok(NonMetric::Acre),
@ -200,6 +213,19 @@ fn parse_unit(input: String) -> Result<NonMetric, ParseError> {
"feet^3" => Ok(NonMetric::CubicFoot),
"ft^3" => Ok(NonMetric::CubicFoot),
"cubic yard" => Ok(NonMetric::CubicYard),
"cubic yards" => Ok(NonMetric::CubicYard),
"cubic yd" => Ok(NonMetric::CubicYard),
"cu yard" => Ok(NonMetric::CubicYard),
"cu yards" => Ok(NonMetric::CubicYard),
"cu yd" => Ok(NonMetric::CubicYard),
"yard³" => Ok(NonMetric::CubicYard),
"yards³" => Ok(NonMetric::CubicYard),
"yd³" => Ok(NonMetric::CubicYard),
"yard^3" => Ok(NonMetric::CubicYard),
"yards^3" => Ok(NonMetric::CubicYard),
"yd^3" => Ok(NonMetric::CubicYard),
// Fluid volume
"imperial fluid ounce" => Ok(NonMetric::ImperialFluidOunce),
"imperial fluid ounces" => Ok(NonMetric::ImperialFluidOunce),
@ -550,6 +576,21 @@ mod test {
"sf",
]);
test_units(NonMetric::SquareYard, &[
"square yard",
"square yards",
"square yd",
"sq yard",
"sq yards",
"sq yd",
"yard²",
"yards²",
"yd²",
"yard^2",
"yards^2",
"yd^2",
]);
test_units(NonMetric::Acre, &[
"acre",
"acres",
@ -602,6 +643,21 @@ mod test {
"ft^3",
]);
test_units(NonMetric::CubicYard, &[
"cubic yard",
"cubic yards",
"cubic yd",
"cu yard",
"cu yards",
"cu yd",
"yard³",
"yards³",
"yd³",
"yard^3",
"yards^3",
"yd^3",
]);
// Fluid volume
test_units(NonMetric::ImperialFluidOunce, &[
"imperial fluid ounce",

View File

@ -26,11 +26,13 @@ pub enum NonMetric {
// Area
SquareInch,
SquareFoot,
SquareYard,
Acre,
SquareMile,
// Volume
CubicInch,
CubicFoot,
CubicYard,
// Fluid volume
ImperialFluidOunce,
ImperialPint,