Add support for data rate units
This permits the following calculations: 10 kilobytes per second * 6 seconds = 60 kilobytes 500 megabytes / 100 megabytes per second = 5 seconds 1 gibibit per second * 1 hour = 3600 gibibits
This commit is contained in:
parent
f45aae15e0
commit
45dfe129dc
@ -1,5 +1,6 @@
|
||||
## Next
|
||||
- Add support for dividing length units by speed units (like 10 km / 100 kph)
|
||||
- Add support for data transfer rate units (eg. megabytes per second)
|
||||
|
||||
## 1.7.0 - 2021 Jul 14
|
||||
- Add operator words `plus`, `minus` and `times`
|
||||
|
||||
236
src/lexer.rs
236
src/lexer.rs
@ -428,6 +428,16 @@ fn parse_word(word: &str, lexer: &mut Lexer) -> Result<(), String> {
|
||||
"zib" | "zebibyte" | "zebibytes" => Token::Unit(Zebibyte),
|
||||
"yib" | "yobibyte" | "yobibytes" => Token::Unit(Yobibyte),
|
||||
|
||||
"bps" => Token::Unit(BitsPerSecond),
|
||||
"kbps" => Token::Unit(KilobitsPerSecond),
|
||||
"mbps" => Token::Unit(MegabitsPerSecond),
|
||||
"gbps" => Token::Unit(GigabitsPerSecond),
|
||||
"tbps" => Token::Unit(TerabitsPerSecond),
|
||||
"pbps" => Token::Unit(PetabitsPerSecond),
|
||||
"ebps" => Token::Unit(ExabitsPerSecond),
|
||||
"zbps" => Token::Unit(ZettabitsPerSecond),
|
||||
"ybps" => Token::Unit(YottabitsPerSecond),
|
||||
|
||||
"millijoule" | "millijoules" => Token::Unit(Millijoule),
|
||||
"j"| "joule" | "joules" => Token::Unit(Joule),
|
||||
"nm" => Token::Unit(NewtonMeter),
|
||||
@ -750,6 +760,142 @@ pub fn lex(input: &str, remove_trailing_operator: bool, default_degree: Unit) ->
|
||||
(Token::Unit(Foot), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(FeetPerSecond);
|
||||
},
|
||||
// bits per second
|
||||
(Token::Unit(Bit), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(BitsPerSecond);
|
||||
},
|
||||
// kilobits per second
|
||||
(Token::Unit(Kilobit), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(KilobitsPerSecond);
|
||||
},
|
||||
// megabits per second
|
||||
(Token::Unit(Megabit), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(MegabitsPerSecond);
|
||||
},
|
||||
// gigabits per second
|
||||
(Token::Unit(Gigabit), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(GigabitsPerSecond);
|
||||
},
|
||||
// terabits per second
|
||||
(Token::Unit(Terabit), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(TerabitsPerSecond);
|
||||
},
|
||||
// petabits per second
|
||||
(Token::Unit(Petabit), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(PetabitsPerSecond);
|
||||
},
|
||||
// exabits per second
|
||||
(Token::Unit(Exabit), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(ExabitsPerSecond);
|
||||
},
|
||||
// zettabits per second
|
||||
(Token::Unit(Zettabit), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(ZettabitsPerSecond);
|
||||
},
|
||||
// yottabits per second
|
||||
(Token::Unit(Yottabit), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(YottabitsPerSecond);
|
||||
},
|
||||
// kibibits per second
|
||||
(Token::Unit(Kibibit), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(KibibitsPerSecond);
|
||||
},
|
||||
// mebibits per second
|
||||
(Token::Unit(Mebibit), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(MebibitsPerSecond);
|
||||
},
|
||||
// gibibits per second
|
||||
(Token::Unit(Gibibit), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(GibibitsPerSecond);
|
||||
},
|
||||
// tebibits per second
|
||||
(Token::Unit(Tebibit), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(TebibitsPerSecond);
|
||||
},
|
||||
// pebibits per second
|
||||
(Token::Unit(Pebibit), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(PebibitsPerSecond);
|
||||
},
|
||||
// exbibits per second
|
||||
(Token::Unit(Exbibit), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(ExbibitsPerSecond);
|
||||
},
|
||||
// zebibits per second
|
||||
(Token::Unit(Zebibit), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(ZebibitsPerSecond);
|
||||
},
|
||||
// yobibits per second
|
||||
(Token::Unit(Yobibit), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(YobibitsPerSecond);
|
||||
},
|
||||
// bytes per second
|
||||
(Token::Unit(Byte), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(BytesPerSecond);
|
||||
},
|
||||
// kilobytes per second
|
||||
(Token::Unit(Kilobyte), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(KilobytesPerSecond);
|
||||
},
|
||||
// megabytes per second
|
||||
(Token::Unit(Megabyte), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(MegabytesPerSecond);
|
||||
},
|
||||
// gigabytes per second
|
||||
(Token::Unit(Gigabyte), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(GigabytesPerSecond);
|
||||
},
|
||||
// terabytes per second
|
||||
(Token::Unit(Terabyte), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(TerabytesPerSecond);
|
||||
},
|
||||
// petabytes per second
|
||||
(Token::Unit(Petabyte), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(PetabytesPerSecond);
|
||||
},
|
||||
// exabytes per second
|
||||
(Token::Unit(Exabyte), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(ExabytesPerSecond);
|
||||
},
|
||||
// zettabytes per second
|
||||
(Token::Unit(Zettabyte), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(ZettabytesPerSecond);
|
||||
},
|
||||
// yottabytes per second
|
||||
(Token::Unit(Yottabyte), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(YottabytesPerSecond);
|
||||
},
|
||||
// kibibytes per second
|
||||
(Token::Unit(Kibibyte), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(KibibytesPerSecond);
|
||||
},
|
||||
// mebibytes per second
|
||||
(Token::Unit(Mebibyte), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(MebibytesPerSecond);
|
||||
},
|
||||
// gibibytes per second
|
||||
(Token::Unit(Gibibyte), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(GibibytesPerSecond);
|
||||
},
|
||||
// tebibytes per second
|
||||
(Token::Unit(Tebibyte), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(TebibytesPerSecond);
|
||||
},
|
||||
// pebibytes per second
|
||||
(Token::Unit(Pebibyte), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(PebibytesPerSecond);
|
||||
},
|
||||
// exbibytes per second
|
||||
(Token::Unit(Exbibyte), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(ExbibytesPerSecond);
|
||||
},
|
||||
// zebibytes per second
|
||||
(Token::Unit(Zebibyte), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(ZebibytesPerSecond);
|
||||
},
|
||||
// yobibytes per second
|
||||
(Token::Unit(Yobibyte), Token::LexerKeyword(Per), Token::Unit(Second)) => {
|
||||
tokens[token_index-2] = Token::Unit(YobibytesPerSecond);
|
||||
},
|
||||
// btu/min
|
||||
(Token::Unit(BritishThermalUnit), Token::LexerKeyword(Per), Token::Unit(Minute)) => {
|
||||
tokens[token_index-2] = Token::Unit(BritishThermalUnitsPerMinute);
|
||||
@ -800,6 +946,7 @@ mod tests {
|
||||
fn test_lex() {
|
||||
let strip_operator_spacing = Regex::new(r" ([+\-*/]) ").unwrap();
|
||||
let strip_afterdigit_spacing = Regex::new(r"(\d) ").unwrap();
|
||||
let nonplural_data_units = Regex::new(r"(bit|byte)s").unwrap();
|
||||
|
||||
let run_lex = |input: &str, expected_tokens: Vec<Token>| {
|
||||
let tokens = match lex(input, false, Unit::Celsius) {
|
||||
@ -827,6 +974,16 @@ mod tests {
|
||||
assert!(tokens_afterdigit_stripped_spaces == expected_tokens, "{}", info_msg);
|
||||
};
|
||||
|
||||
let run_datarate_lex = |input: &str, expected_tokens: Vec<Token>| {
|
||||
run_lex(input, (*expected_tokens).to_vec());
|
||||
|
||||
// Prove plural and non-plural data units behave identically
|
||||
let input_nonplural_units = nonplural_data_units.replace_all(input, "$1");
|
||||
let tokens_nonplural_units = lex(&input_nonplural_units, false, Unit::Celsius).unwrap();
|
||||
let info_msg = format!("run_datarate_lex input: {}\nexpected: {:?}\nreceived: {:?}", input, expected_tokens, tokens_nonplural_units);
|
||||
assert!(tokens_nonplural_units == expected_tokens, "{}", info_msg);
|
||||
};
|
||||
|
||||
run_lex("88 kilometres * 2", vec![numtok!(88), Token::Unit(Kilometer), Token::Operator(Multiply), numtok!(2)]);
|
||||
run_lex("100 nmi", vec![numtok!(100), Token::Unit(NauticalMile)]);
|
||||
run_lex("101 nautical miles", vec![numtok!(101), Token::Unit(NauticalMile)]);
|
||||
@ -861,6 +1018,85 @@ mod tests {
|
||||
run_lex("3 short tons", vec![numtok!(3), Token::Unit(ShortTon)]);
|
||||
run_lex("4 lt", vec![numtok!(4), Token::Unit(LongTon)]);
|
||||
run_lex("4 long tonnes", vec![numtok!(4), Token::Unit(LongTon)]);
|
||||
run_datarate_lex("1 bit", vec![numtok!(1), Token::Unit(Bit)]);
|
||||
run_datarate_lex("8 bits", vec![numtok!(8), Token::Unit(Bit)]);
|
||||
run_datarate_lex("63 kilobits", vec![numtok!(63), Token::Unit(Kilobit)]);
|
||||
run_datarate_lex("32 megabits", vec![numtok!(32), Token::Unit(Megabit)]);
|
||||
run_datarate_lex("3.5 gigabits", vec![numtok!(3.5), Token::Unit(Gigabit)]);
|
||||
run_datarate_lex("2.1 terabits", vec![numtok!(2.1), Token::Unit(Terabit)]);
|
||||
run_datarate_lex("1.08 petabits", vec![numtok!(1.08), Token::Unit(Petabit)]);
|
||||
run_datarate_lex("0.73 exabits", vec![numtok!(0.73), Token::Unit(Exabit)]);
|
||||
run_datarate_lex("0.49 zettabits", vec![numtok!(0.49), Token::Unit(Zettabit)]);
|
||||
run_datarate_lex("0.23 yottabits", vec![numtok!(0.23), Token::Unit(Yottabit)]);
|
||||
run_datarate_lex("63 kibibits", vec![numtok!(63), Token::Unit(Kibibit)]);
|
||||
run_datarate_lex("32 mebibits", vec![numtok!(32), Token::Unit(Mebibit)]);
|
||||
run_datarate_lex("3.5 gibibits", vec![numtok!(3.5), Token::Unit(Gibibit)]);
|
||||
run_datarate_lex("2.1 tebibits", vec![numtok!(2.1), Token::Unit(Tebibit)]);
|
||||
run_datarate_lex("1.08 pebibits", vec![numtok!(1.08), Token::Unit(Pebibit)]);
|
||||
run_datarate_lex("0.73 exbibits", vec![numtok!(0.73), Token::Unit(Exbibit)]);
|
||||
run_datarate_lex("0.49 zebibits", vec![numtok!(0.49), Token::Unit(Zebibit)]);
|
||||
run_datarate_lex("0.23 yobibits", vec![numtok!(0.23), Token::Unit(Yobibit)]);
|
||||
run_datarate_lex("1 byte", vec![numtok!(1), Token::Unit(Byte)]);
|
||||
run_datarate_lex("3 bytes", vec![numtok!(3), Token::Unit(Byte)]);
|
||||
run_datarate_lex("63 kilobytes", vec![numtok!(63), Token::Unit(Kilobyte)]);
|
||||
run_datarate_lex("32 megabytes", vec![numtok!(32), Token::Unit(Megabyte)]);
|
||||
run_datarate_lex("3.5 gigabytes", vec![numtok!(3.5), Token::Unit(Gigabyte)]);
|
||||
run_datarate_lex("2.1 terabytes", vec![numtok!(2.1), Token::Unit(Terabyte)]);
|
||||
run_datarate_lex("1.08 petabytes", vec![numtok!(1.08), Token::Unit(Petabyte)]);
|
||||
run_datarate_lex("0.73 exabytes", vec![numtok!(0.73), Token::Unit(Exabyte)]);
|
||||
run_datarate_lex("0.49 zettabytes", vec![numtok!(0.49), Token::Unit(Zettabyte)]);
|
||||
run_datarate_lex("0.23 yottabytes", vec![numtok!(0.23), Token::Unit(Yottabyte)]);
|
||||
run_datarate_lex("63 kibibytes", vec![numtok!(63), Token::Unit(Kibibyte)]);
|
||||
run_datarate_lex("32 mebibytes", vec![numtok!(32), Token::Unit(Mebibyte)]);
|
||||
run_datarate_lex("3.5 gibibytes", vec![numtok!(3.5), Token::Unit(Gibibyte)]);
|
||||
run_datarate_lex("2.1 tebibytes", vec![numtok!(2.1), Token::Unit(Tebibyte)]);
|
||||
run_datarate_lex("1.08 pebibytes", vec![numtok!(1.08), Token::Unit(Pebibyte)]);
|
||||
run_datarate_lex("0.73 exbibytes", vec![numtok!(0.73), Token::Unit(Exbibyte)]);
|
||||
run_datarate_lex("0.49 zebibytes", vec![numtok!(0.49), Token::Unit(Zebibyte)]);
|
||||
run_datarate_lex("0.23 yobibytes", vec![numtok!(0.23), Token::Unit(Yobibyte)]);
|
||||
run_lex("432 bps", vec![numtok!(432), Token::Unit(BitsPerSecond)]);
|
||||
run_lex("56 kbps", vec![numtok!(56), Token::Unit(KilobitsPerSecond)]);
|
||||
run_lex("12 mbps", vec![numtok!(12), Token::Unit(MegabitsPerSecond)]);
|
||||
run_lex("4.2 gbps", vec![numtok!(4.2), Token::Unit(GigabitsPerSecond)]);
|
||||
run_lex("2.2 tbps", vec![numtok!(2.2), Token::Unit(TerabitsPerSecond)]);
|
||||
run_lex("1.7 pbps", vec![numtok!(1.7), Token::Unit(PetabitsPerSecond)]);
|
||||
run_lex("0.99 ebps", vec![numtok!(0.99), Token::Unit(ExabitsPerSecond)]);
|
||||
run_lex("0.64 zbps", vec![numtok!(0.64), Token::Unit(ZettabitsPerSecond)]);
|
||||
run_lex("0.278 ybps", vec![numtok!(0.278), Token::Unit(YottabitsPerSecond)]);
|
||||
run_datarate_lex("4 bits per second", vec![numtok!(4), Token::Unit(BitsPerSecond)]);
|
||||
run_datarate_lex("5 kilobits per second", vec![numtok!(5), Token::Unit(KilobitsPerSecond)]);
|
||||
run_datarate_lex("6 megabits per second", vec![numtok!(6), Token::Unit(MegabitsPerSecond)]);
|
||||
run_datarate_lex("7 gigabits per second", vec![numtok!(7), Token::Unit(GigabitsPerSecond)]);
|
||||
run_datarate_lex("8 terabits per second", vec![numtok!(8), Token::Unit(TerabitsPerSecond)]);
|
||||
run_datarate_lex("9 petabits per second", vec![numtok!(9), Token::Unit(PetabitsPerSecond)]);
|
||||
run_datarate_lex("10 exabits per second", vec![numtok!(10), Token::Unit(ExabitsPerSecond)]);
|
||||
run_datarate_lex("11 zettabits per second", vec![numtok!(11), Token::Unit(ZettabitsPerSecond)]);
|
||||
run_datarate_lex("12 yottabits per second", vec![numtok!(12), Token::Unit(YottabitsPerSecond)]);
|
||||
run_datarate_lex("13 kibibits per second", vec![numtok!(13), Token::Unit(KibibitsPerSecond)]);
|
||||
run_datarate_lex("14 mebibits per second", vec![numtok!(14), Token::Unit(MebibitsPerSecond)]);
|
||||
run_datarate_lex("15 gibibits per second", vec![numtok!(15), Token::Unit(GibibitsPerSecond)]);
|
||||
run_datarate_lex("16 tebibits per second", vec![numtok!(16), Token::Unit(TebibitsPerSecond)]);
|
||||
run_datarate_lex("17 pebibits per second", vec![numtok!(17), Token::Unit(PebibitsPerSecond)]);
|
||||
run_datarate_lex("18 exbibits per second", vec![numtok!(18), Token::Unit(ExbibitsPerSecond)]);
|
||||
run_datarate_lex("19 zebibits per second", vec![numtok!(19), Token::Unit(ZebibitsPerSecond)]);
|
||||
run_datarate_lex("20 yobibits per second", vec![numtok!(20), Token::Unit(YobibitsPerSecond)]);
|
||||
run_datarate_lex("4 bytes per second", vec![numtok!(4), Token::Unit(BytesPerSecond)]);
|
||||
run_datarate_lex("5 kilobytes per second", vec![numtok!(5), Token::Unit(KilobytesPerSecond)]);
|
||||
run_datarate_lex("6 megabytes per second", vec![numtok!(6), Token::Unit(MegabytesPerSecond)]);
|
||||
run_datarate_lex("7 gigabytes per second", vec![numtok!(7), Token::Unit(GigabytesPerSecond)]);
|
||||
run_datarate_lex("8 terabytes per second", vec![numtok!(8), Token::Unit(TerabytesPerSecond)]);
|
||||
run_datarate_lex("9 petabytes per second", vec![numtok!(9), Token::Unit(PetabytesPerSecond)]);
|
||||
run_datarate_lex("10 exabytes per second", vec![numtok!(10), Token::Unit(ExabytesPerSecond)]);
|
||||
run_datarate_lex("11 zettabytes per second", vec![numtok!(11), Token::Unit(ZettabytesPerSecond)]);
|
||||
run_datarate_lex("12 yottabytes per second", vec![numtok!(12), Token::Unit(YottabytesPerSecond)]);
|
||||
run_datarate_lex("13 kibibytes per second", vec![numtok!(13), Token::Unit(KibibytesPerSecond)]);
|
||||
run_datarate_lex("14 mebibytes per second", vec![numtok!(14), Token::Unit(MebibytesPerSecond)]);
|
||||
run_datarate_lex("15 gibibytes per second", vec![numtok!(15), Token::Unit(GibibytesPerSecond)]);
|
||||
run_datarate_lex("16 tebibytes per second", vec![numtok!(16), Token::Unit(TebibytesPerSecond)]);
|
||||
run_datarate_lex("17 pebibytes per second", vec![numtok!(17), Token::Unit(PebibytesPerSecond)]);
|
||||
run_datarate_lex("18 exbibytes per second", vec![numtok!(18), Token::Unit(ExbibytesPerSecond)]);
|
||||
run_datarate_lex("19 zebibytes per second", vec![numtok!(19), Token::Unit(ZebibytesPerSecond)]);
|
||||
run_datarate_lex("20 yobibytes per second", vec![numtok!(20), Token::Unit(YobibytesPerSecond)]);
|
||||
run_lex("234 wh", vec![numtok!(234), Token::Unit(WattHour)]);
|
||||
run_lex("1 w", vec![numtok!(1), Token::Unit(Watt)]);
|
||||
run_lex("1 watt", vec![numtok!(1), Token::Unit(Watt)]);
|
||||
|
||||
120
src/units.rs
120
src/units.rs
@ -19,6 +19,8 @@ pub enum UnitType {
|
||||
Mass,
|
||||
/// A unit of digital storage, for example [`Kilobyte`]
|
||||
DigitalStorage,
|
||||
/// A unit of data rate transfer, for example [`KilobytesPerSecond`]
|
||||
DataTransferRate,
|
||||
/// A unit of energy, for example [`Joule`] or [`KilowattHour`]
|
||||
Energy,
|
||||
/// A unit of power, for example [`Watt`]
|
||||
@ -187,6 +189,41 @@ create_units!(
|
||||
Zebibyte: (DigitalStorage, d128!(9444732965739290427392)),
|
||||
Yobibyte: (DigitalStorage, d128!(9671406556917033397649408)),
|
||||
|
||||
BitsPerSecond: (DataTransferRate, d128!(1)),
|
||||
KilobitsPerSecond: (DataTransferRate, d128!(1000)),
|
||||
MegabitsPerSecond: (DataTransferRate, d128!(1000000)),
|
||||
GigabitsPerSecond: (DataTransferRate, d128!(1000000000)),
|
||||
TerabitsPerSecond: (DataTransferRate, d128!(1000000000000)),
|
||||
PetabitsPerSecond: (DataTransferRate, d128!(1000000000000000)),
|
||||
ExabitsPerSecond: (DataTransferRate, d128!(1000000000000000000)),
|
||||
ZettabitsPerSecond: (DataTransferRate, d128!(1000000000000000000000)),
|
||||
YottabitsPerSecond: (DataTransferRate, d128!(1000000000000000000000000)),
|
||||
KibibitsPerSecond: (DataTransferRate, d128!(1024)),
|
||||
MebibitsPerSecond: (DataTransferRate, d128!(1048576)),
|
||||
GibibitsPerSecond: (DataTransferRate, d128!(1073741824)),
|
||||
TebibitsPerSecond: (DataTransferRate, d128!(1099511627776)),
|
||||
PebibitsPerSecond: (DataTransferRate, d128!(1125899906842624)),
|
||||
ExbibitsPerSecond: (DataTransferRate, d128!(1152921504606846976)),
|
||||
ZebibitsPerSecond: (DataTransferRate, d128!(1180591620717411303424)),
|
||||
YobibitsPerSecond: (DataTransferRate, d128!(1208925819614629174706176)),
|
||||
BytesPerSecond: (DataTransferRate, d128!(8)),
|
||||
KilobytesPerSecond: (DataTransferRate, d128!(8000)),
|
||||
MegabytesPerSecond: (DataTransferRate, d128!(8000000)),
|
||||
GigabytesPerSecond: (DataTransferRate, d128!(8000000000)),
|
||||
TerabytesPerSecond: (DataTransferRate, d128!(8000000000000)),
|
||||
PetabytesPerSecond: (DataTransferRate, d128!(8000000000000000)),
|
||||
ExabytesPerSecond: (DataTransferRate, d128!(8000000000000000000)),
|
||||
ZettabytesPerSecond: (DataTransferRate, d128!(8000000000000000000000)),
|
||||
YottabytesPerSecond: (DataTransferRate, d128!(8000000000000000000000000)),
|
||||
KibibytesPerSecond: (DataTransferRate, d128!(8192)),
|
||||
MebibytesPerSecond: (DataTransferRate, d128!(8388608)),
|
||||
GibibytesPerSecond: (DataTransferRate, d128!(8589934592)),
|
||||
TebibytesPerSecond: (DataTransferRate, d128!(8796093022208)),
|
||||
PebibytesPerSecond: (DataTransferRate, d128!(9007199254740992)),
|
||||
ExbibytesPerSecond: (DataTransferRate, d128!(9223372036854775808)),
|
||||
ZebibytesPerSecond: (DataTransferRate, d128!(9444732965739290427392)),
|
||||
YobibytesPerSecond: (DataTransferRate, d128!(9671406556917033397649408)),
|
||||
|
||||
// ! If updating Millijoule, also update get_inverted_millijoule_weight()
|
||||
Millijoule: (Energy, d128!(0.001)),
|
||||
Joule: (Energy, d128!(1)),
|
||||
@ -551,6 +588,50 @@ fn actual_multiply(left: Number, right: Number, swapped: bool) -> Result<Number,
|
||||
};
|
||||
let kilometers = Number::new(result, Kilometer);
|
||||
Ok(convert(kilometers, final_unit)?)
|
||||
} else if lcat == DataTransferRate && rcat == Time {
|
||||
// 8 megabytes per second * 1 minute
|
||||
let data_rate_value = left.value * left.unit.weight();
|
||||
let seconds = convert(right, Second)?;
|
||||
let result = data_rate_value * seconds.value;
|
||||
let final_unit = match left.unit {
|
||||
BitsPerSecond => Bit,
|
||||
KilobitsPerSecond => Kilobit,
|
||||
MegabitsPerSecond => Megabit,
|
||||
GigabitsPerSecond => Gigabit,
|
||||
TerabitsPerSecond => Terabit,
|
||||
PetabitsPerSecond => Petabit,
|
||||
ExabitsPerSecond => Exabit,
|
||||
ZettabitsPerSecond => Zettabit,
|
||||
YottabitsPerSecond => Yottabit,
|
||||
KibibitsPerSecond => Kibibit,
|
||||
MebibitsPerSecond => Mebibit,
|
||||
GibibitsPerSecond => Gibibit,
|
||||
TebibitsPerSecond => Tebibit,
|
||||
PebibitsPerSecond => Pebibit,
|
||||
ExbibitsPerSecond => Exbibit,
|
||||
ZebibitsPerSecond => Zebibit,
|
||||
YobibitsPerSecond => Yobibit,
|
||||
BytesPerSecond => Byte,
|
||||
KilobytesPerSecond => Kilobyte,
|
||||
MegabytesPerSecond => Megabyte,
|
||||
GigabytesPerSecond => Gigabyte,
|
||||
TerabytesPerSecond => Terabyte,
|
||||
PetabytesPerSecond => Petabyte,
|
||||
ExabytesPerSecond => Exabyte,
|
||||
ZettabytesPerSecond => Zettabyte,
|
||||
YottabytesPerSecond => Yottabyte,
|
||||
KibibytesPerSecond => Kibibyte,
|
||||
MebibytesPerSecond => Mebibyte,
|
||||
GibibytesPerSecond => Gibibyte,
|
||||
TebibytesPerSecond => Tebibyte,
|
||||
PebibytesPerSecond => Pebibyte,
|
||||
ExbibytesPerSecond => Exbibyte,
|
||||
ZebibytesPerSecond => Zebibyte,
|
||||
YobibytesPerSecond => Yobibyte,
|
||||
_ => Bit,
|
||||
};
|
||||
let data_storage = Number::new(result, Bit);
|
||||
Ok(convert(data_storage, final_unit)?)
|
||||
} else if lcat == Voltage && rcat == ElectricCurrent {
|
||||
// 1 volt * 1 ampere = 1 watt
|
||||
let result = (left.value * left.unit.weight()) * (right.value * right.unit.weight());
|
||||
@ -631,6 +712,12 @@ pub fn divide(left: Number, right: Number) -> Result<Number, String> {
|
||||
let kilometers_per_hour = convert(right, KilometersPerHour)?;
|
||||
let hour = Number::new(kilometers.value / kilometers_per_hour.value, Hour);
|
||||
Ok(to_ideal_unit(hour))
|
||||
} else if lcat == DigitalStorage && rcat == DataTransferRate {
|
||||
// 1 kilobit / 1 bit per second
|
||||
let bits = convert(left, Bit)?;
|
||||
let bits_per_second = convert(right, BitsPerSecond)?;
|
||||
let seconds = Number::new(bits.value / bits_per_second.value, Second);
|
||||
Ok(to_ideal_unit(seconds))
|
||||
} else if lcat == Power && rcat == ElectricCurrent {
|
||||
// 1 watt / 1 ampere = 1 volt
|
||||
let result = (left.value * left.unit.weight()) / (right.value * right.unit.weight());
|
||||
@ -840,6 +927,39 @@ mod tests {
|
||||
assert_float_eq!(convert_test(1024.0, Exbibyte, Zebibyte), 1.0);
|
||||
assert_float_eq!(convert_test(1024.0, Zebibyte, Yobibyte), 1.0);
|
||||
|
||||
assert_float_eq!(convert_test(1000.0, BitsPerSecond, KilobitsPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1000.0, KilobitsPerSecond, MegabitsPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1000.0, MegabitsPerSecond, GigabitsPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1000.0, GigabitsPerSecond, TerabitsPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1000.0, TerabitsPerSecond, PetabitsPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1000.0, PetabitsPerSecond, ExabitsPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1000.0, ExabitsPerSecond, ZettabitsPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1000.0, ZettabitsPerSecond, YottabitsPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1024.0, BitsPerSecond, KibibitsPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1024.0, KibibitsPerSecond, MebibitsPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1024.0, MebibitsPerSecond, GibibitsPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1024.0, GibibitsPerSecond, TebibitsPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1024.0, TebibitsPerSecond, PebibitsPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1024.0, PebibitsPerSecond, ExbibitsPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1024.0, ExbibitsPerSecond, ZebibitsPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1024.0, ZebibitsPerSecond, YobibitsPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(8.0, BitsPerSecond, BytesPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1000.0, BytesPerSecond, KilobytesPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1000.0, KilobytesPerSecond, MegabytesPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1000.0, MegabytesPerSecond, GigabytesPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1000.0, GigabytesPerSecond, TerabytesPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1000.0, TerabytesPerSecond, PetabytesPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1000.0, PetabytesPerSecond, ExabytesPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1000.0, ExabytesPerSecond, ZettabytesPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1000.0, ZettabytesPerSecond, YottabytesPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1024.0, KibibytesPerSecond, MebibytesPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1024.0, MebibytesPerSecond, GibibytesPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1024.0, GibibytesPerSecond, TebibytesPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1024.0, TebibytesPerSecond, PebibytesPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1024.0, PebibytesPerSecond, ExbibytesPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1024.0, ExbibytesPerSecond, ZebibytesPerSecond), 1.0);
|
||||
assert_float_eq!(convert_test(1024.0, ZebibytesPerSecond, YobibytesPerSecond), 1.0);
|
||||
|
||||
assert_float_eq!(convert_test(1000.0, Millijoule, Joule), 1.0);
|
||||
assert_float_eq!(convert_test(1000.0, Joule, Kilojoule), 1.0);
|
||||
assert_float_eq!(convert_test(1.0, NewtonMeter, Joule), 1.0);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user