• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use nom::branch::alt;
2 use nom::bytes::complete::tag;
3 use nom::character::streaming::digit1 as digit;
4 use nom::combinator::{map, map_res, opt, recognize};
5 use nom::sequence::{delimited, pair};
6 use nom::IResult;
7 
8 use std::str;
9 use std::str::FromStr;
10 
unsigned_float(i: &[u8]) -> IResult<&[u8], f32>11 fn unsigned_float(i: &[u8]) -> IResult<&[u8], f32> {
12   let float_bytes = recognize(alt((
13     delimited(digit, tag("."), opt(digit)),
14     delimited(opt(digit), tag("."), digit),
15   )));
16   let float_str = map_res(float_bytes, str::from_utf8);
17   map_res(float_str, FromStr::from_str)(i)
18 }
19 
float(i: &[u8]) -> IResult<&[u8], f32>20 fn float(i: &[u8]) -> IResult<&[u8], f32> {
21   map(
22     pair(opt(alt((tag("+"), tag("-")))), unsigned_float),
23     |(sign, value)| {
24       sign
25         .and_then(|s| if s[0] == b'-' { Some(-1f32) } else { None })
26         .unwrap_or(1f32)
27         * value
28     },
29   )(i)
30 }
31 
32 #[test]
unsigned_float_test()33 fn unsigned_float_test() {
34   assert_eq!(unsigned_float(&b"123.456;"[..]), Ok((&b";"[..], 123.456)));
35   assert_eq!(unsigned_float(&b"0.123;"[..]), Ok((&b";"[..], 0.123)));
36   assert_eq!(unsigned_float(&b"123.0;"[..]), Ok((&b";"[..], 123.0)));
37   assert_eq!(unsigned_float(&b"123.;"[..]), Ok((&b";"[..], 123.0)));
38   assert_eq!(unsigned_float(&b".123;"[..]), Ok((&b";"[..], 0.123)));
39 }
40 
41 #[test]
float_test()42 fn float_test() {
43   assert_eq!(float(&b"123.456;"[..]), Ok((&b";"[..], 123.456)));
44   assert_eq!(float(&b"+123.456;"[..]), Ok((&b";"[..], 123.456)));
45   assert_eq!(float(&b"-123.456;"[..]), Ok((&b";"[..], -123.456)));
46 }
47