nrc_protobuf_codegen/
float.rs1use std::f64;
2
3#[derive(Debug)]
4pub enum ProtobufFloatParseError {
5 EmptyString,
6 CannotParseFloat,
7}
8
9pub type ProtobufFloatParseResult<T> = Result<T, ProtobufFloatParseError>;
10
11pub const PROTOBUF_NAN: &str = "nan";
12pub const PROTOBUF_INF: &str = "inf";
13
14pub fn format_protobuf_float(f: f64) -> String {
16 if f.is_nan() {
17 PROTOBUF_NAN.to_owned()
18 } else if f.is_infinite() {
19 if f > 0.0 {
20 format!("{}", PROTOBUF_INF)
21 } else {
22 format!("-{}", PROTOBUF_INF)
23 }
24 } else {
25 let i = f as i64;
26 if i as f64 == f {
27 format!("{:?}.0", i)
29 } else {
30 format!("{:?}", f)
32 }
33 }
34}
35
36pub fn parse_protobuf_float(s: &str) -> ProtobufFloatParseResult<f64> {
38 if s.is_empty() {
39 return Err(ProtobufFloatParseError::EmptyString);
40 }
41 if s == PROTOBUF_NAN {
42 return Ok(f64::NAN);
43 }
44 if s == PROTOBUF_INF || s == format!("+{}", PROTOBUF_INF) {
45 return Ok(f64::INFINITY);
46 }
47 if s == format!("-{}", PROTOBUF_INF) {
48 return Ok(f64::NEG_INFINITY);
49 }
50 match s.parse() {
51 Ok(f) => Ok(f),
52 Err(_) => Err(ProtobufFloatParseError::CannotParseFloat),
53 }
54}
55
56#[cfg(test)]
57mod test {
58 use super::*;
59
60 #[test]
61 fn test_format_protobuf_float() {
62 assert_eq!("10.0", format_protobuf_float(10.0));
63 assert_eq!("-10.0", format_protobuf_float(-10.0));
64 assert_eq!("10.5", format_protobuf_float(10.5));
65 assert_eq!("-10.5", format_protobuf_float(-10.5));
66 }
67}