pub struct NumberParser {
pub settings: NumberParserSettings,
}
Expand description
Provide for parsing of numbers in various forms.
To use this, make an instance and then configure it if you wish.
§Plus / Minus
(Signed) numbers can start with an optional minus or plus sign to indicate the
sign. If you do not want to allow the plus sign, see NumberParserSettings::permit_plus
.
§Permitted Radices
The methods Self::parse_u128
, Self::parse_i128
, and Self::parse_f64
,
can parse numbers that occur in any supported radix. You can disable parsing of
numbers in hexadecimal, octal, or binary by setting the appropriate flag to false.
Decimal numbers cannot be disabled.
§Radix Indicator
Different radices can be detected automatically using a leading radix indicator. This is also configurable, with the following defaults.
Prefix | Radix |
---|---|
0b | Binary |
0o | Octal |
none | Decimal |
0x | Hexadecimal |
Radix indicators can be configured if you wish, but you must be careful to avoid excessive ambiguity. The following is an example.
use trivet::numbers::NumberParser;
use trivet::ParserCore;
use trivet::errors::ParseResult;
use trivet::parse_from_string;
let mut parser = parse_from_string("17 $ffef_1021");
let mut core = parser.borrow_core();
let mut numpar = NumberParser::new();
numpar.settings.permit_binary = false;
numpar.settings.permit_octal = false;
numpar.settings.hexadecimal_indicator = vec!['$'];
assert_eq!(numpar.parse_u128(&mut core)?, 17);
core.consume();
assert_eq!(numpar.parse_u128(&mut core)?, 0xffef1021);
§Explicit Radix
Methods that explicitly specify a radix do not look for a radix indicator, and will fail if one is encountered. They also ignore the enabled/disabled status of any radix.
use trivet::numbers::NumberParser;
use trivet::numbers::Radix;
use trivet::ParserCore;
use trivet::errors::ParseResult;
use trivet::parse_from_string;
let mut parser = parse_from_string("17 ffef_1021");
let mut core = parser.borrow_core();
let mut numpar = NumberParser::new();
assert_eq!(numpar.parse_u128_radix(&mut core, Radix::Decimal)?, 17);
let _ = core.consume_ws_only();
assert_eq!(numpar.parse_u128_radix(&mut core, Radix::Hexadecimal)?, 0xffef1021);
Fields§
§settings: NumberParserSettings
The parser settings.
Implementations§
Source§impl NumberParser
impl NumberParser
Sourcepub fn new() -> Self
pub fn new() -> Self
Make a new number parser. All options are enabled by default, and the default radix indicators are installed. This is a very permissive form of number parsing, and can be problematic for some parsers. Check the options carefully to ensure the ones you want are installed.
Examples found in repository?
7pub fn main() {
8 println!("Enter a number to see how Trivet parses it. Enter a blank line to stop.");
9 let numpar = NumberParser::new();
10 print!("> ");
11 let _ = stdout().flush();
12 for line in stdin().lock().lines() {
13 if line.is_err() {
14 break;
15 }
16 let line = line.unwrap();
17
18 // Consume any whitespace.
19 let mut parser = parse_from_string(&line);
20 parser.consume_ws();
21 if parser.is_at_eof() {
22 break;
23 }
24
25 // Try to read a number as pieces.
26 let parts = numpar.get_parts(parser.borrow_core());
27 println!("{:?}", parts);
28 if parts.is_apparent_float() {
29 let value: f64 = parts.into();
30 println!("f64: {}", value);
31 } else {
32 let value: i128 = parts.into();
33 println!("i128: {}", value);
34 }
35
36 // Go around again.
37 print!("> ");
38 let _ = stdout().flush();
39 }
40}
Sourcepub fn get_text(&self, parser: &mut ParserCore) -> (Radix, String, bool)
pub fn get_text(&self, parser: &mut ParserCore) -> (Radix, String, bool)
Get the text of the next number in the stream. This extracts the longest string that matches the following expression. Note that this may not be a valid number.
[-+]? (indicator)? [0-9a-z_]* ('.' [0-9a-z_]*)? ([eEpP] [0-9a-z_]*)?
The +
can be allowed or disallowed using options, and is discarded from the returned string.
The NumberParserSettings::decimal_only_floats
flag is ignored. It can be checked after
returning the result.
In the above indicator
is any allowed radix indicator. The returned value will be a triple
consisting of the apparent radix of the number, the text of the number, and a flag indicating
whether the number is a floating point value.
The exponent indicator p
is required iff the number is in hexadecimal. The exponent indicator
p
is prohibited if hexadecimal is not allowed.
This method honors the settings, so only permitted radices and the appropriate indicators are used, and underscores may or may not be permitted.
Note that even if underscores are permitted, they are discarded during parsing.
Note that tests for leading zero, empty whole, and empty fracitonal part are not performed here. Perform those on evaluation.
Several methods may be useful with respect to the output of this method.
i16::from_str_radix
i32::from_str_radix
i64::from_str_radix
i128::from_str_radix
u16::from_str_radix
u32::from_str_radix
u64::from_str_radix
u128::from_str_radix
f64::from_str
(must usestd::str::FromStr
)
use trivet::parse_from_string;
use trivet::numbers::NumberParser;
use trivet::numbers::Radix;
// Parse an integer value.
let mut parser = parse_from_string("-0x21_e4");
let mut np = NumberParser::new();
let (radix, text, fp) = np.get_text(parser.borrow_core());
assert_eq!(radix, Radix::Hexadecimal);
assert_eq!(text, "-21e4".to_string());
assert_eq!(fp, false);
let value = i16::from_str_radix(&text, radix.value());
assert_eq!(value, Ok(-0x21e4));
use trivet::parse_from_string;
use trivet::numbers::NumberParser;
use trivet::numbers::Radix;
use std::str::FromStr;
// Parse a floating point value.
let mut parser = parse_from_string("-174.0210");
let mut np = NumberParser::new();
let (radix, text, fp) = np.get_text(parser.borrow_core());
assert_eq!(radix, Radix::Decimal);
assert_eq!(text, "-174.0210".to_string());
assert_eq!(fp, true);
let value = f64::from_str(&text);
assert_eq!(value, Ok(-174.0210));
Sourcepub fn get_parts(&self, parser: &mut ParserCore) -> NumberParts
pub fn get_parts(&self, parser: &mut ParserCore) -> NumberParts
Parse text from the stream to generate the parts of a number.
Examples found in repository?
7pub fn main() {
8 println!("Enter a number to see how Trivet parses it. Enter a blank line to stop.");
9 let numpar = NumberParser::new();
10 print!("> ");
11 let _ = stdout().flush();
12 for line in stdin().lock().lines() {
13 if line.is_err() {
14 break;
15 }
16 let line = line.unwrap();
17
18 // Consume any whitespace.
19 let mut parser = parse_from_string(&line);
20 parser.consume_ws();
21 if parser.is_at_eof() {
22 break;
23 }
24
25 // Try to read a number as pieces.
26 let parts = numpar.get_parts(parser.borrow_core());
27 println!("{:?}", parts);
28 if parts.is_apparent_float() {
29 let value: f64 = parts.into();
30 println!("f64: {}", value);
31 } else {
32 let value: i128 = parts.into();
33 println!("i128: {}", value);
34 }
35
36 // Go around again.
37 print!("> ");
38 let _ = stdout().flush();
39 }
40}
Sourcepub fn parse_f64(&self, parser: &mut ParserCore) -> ParseResult<f64>
pub fn parse_f64(&self, parser: &mut ParserCore) -> ParseResult<f64>
Parse a floating point number from the stream. The number’s radix is inferred from any radix prefixes, and only the allowed integer types are checked.
Floating point numbers can be in any supported radix, and the radix indicator is checked. It is it not present, then decimal is assumed. The structure of a floating point number is as follows.
Float ::= '-'? ( Radix)? ( 'inf' | 'infinity' | 'nan' | Number )
Radix ::= ( '0x' | '0o' | '0b' )
Number ::= ( Digit+ |
Digit+ '.' Digit* |
Digit* '.' Digit+ ) Exp?
Exp ::= ('e'|'p') ('-'|'+') Digit+
Digit ::= [0-9a-zA-Z]
Empty whole and fractional parts may be permitted; refer to the
NumberParserSettings::permit_empty_whole
and NumberParserSettings::permit_empty_fraction
settings. A leading zero may be allowed or not. Refer to
NumberParserSettings::permit_leading_zero
.
If both the whole and fractional parts are empty, this is always an error.
The exponent can be indicated with either an e
or a p
. If the radix is hexadecimal,
then only p
can be used to avoid ambiguity.
Some examples.
Number | Value |
---|---|
0,5 | 0.5 |
0b0.1 | 0.5 |
0b1e-1 | 0.5 |
0o0.4 | 0.5 |
0x0.8 | 0.5 |
0x1.4 | 1.25 |
0x3p4 | 196,608 |
0b0.12e-2 | 0.0029296875 |
Caution: This code does not adhere to the IEEE-754 standard for non-decimal bases!
It uses a “best estimate” approach. For base 10 Self::parse_f64_decimal
is used, and
is intended to be compliant.
Sourcepub fn parse_f64_decimal(&self, parser: &mut ParserCore) -> ParseResult<f64>
pub fn parse_f64_decimal(&self, parser: &mut ParserCore) -> ParseResult<f64>
Parse a floating point number from the stream. This method assumes the number will be in decimal and does not look for, or accept, a radix specifier. Underscores are also not accepted here.
The structure of a floating point number is as follows.
Float ::= '-'? ( 'inf' | 'infinity' | 'nan' | Number )
Number ::= ( Digit+ |
Digit+ '.' Digit* |
Digit* '.' Digit+ ) Exp?
Exp ::= [eEpP] ('-'|'+') Digit+
Digit ::= [0-9]
Sourcepub fn parse_i128(&self, parser: &mut ParserCore) -> ParseResult<i128>
pub fn parse_i128(&self, parser: &mut ParserCore) -> ParseResult<i128>
Read an integer from the stream at the current location and compute and return its value. Every alphanumeric character is treated as if it is part of the number. Underscores may be permitted in the number.
Number radices are read and processed here, based on the configuration.
Errors are generated if an unexpected alphanumeric character is encountered during parsing. The first non-alphanumeric stops the parse.
Sourcepub fn parse_u128(&self, parser: &mut ParserCore) -> ParseResult<u128>
pub fn parse_u128(&self, parser: &mut ParserCore) -> ParseResult<u128>
Read an integer from the stream at the current location and compute and return its value. Every alphanumeric character is treated as if it is part of the number. Underscores may be permitted in the number.
Number radices are read and processed here, based on the configuration.
Errors are generated if an unexpected alphanumeric character is encountered during parsing. The first non-alphanumeric stops the parse.
Sourcepub fn parse_i64(&self, parser: &mut ParserCore) -> ParseResult<i64>
pub fn parse_i64(&self, parser: &mut ParserCore) -> ParseResult<i64>
Read an integer from the stream at the current location and compute and return its value. Every alphanumeric character is treated as if it is part of the number. Underscores may be permitted in the number.
Number radices are read and processed here, based on the configuration.
Errors are generated if an unexpected alphanumeric character is encountered during parsing. The first non-alphanumeric stops the parse.
Sourcepub fn parse_u64(&self, parser: &mut ParserCore) -> ParseResult<u64>
pub fn parse_u64(&self, parser: &mut ParserCore) -> ParseResult<u64>
Read an integer from the stream at the current location and compute and return its value. Every alphanumeric character is treated as if it is part of the number. Underscores may be permitted in the number.
Number radices are read and processed here, based on the configuration.
Errors are generated if an unexpected alphanumeric character is encountered during parsing. The first non-alphanumeric stops the parse.
Sourcepub fn parse_i128_radix(
&self,
parser: &mut ParserCore,
radix: Radix,
) -> ParseResult<i128>
pub fn parse_i128_radix( &self, parser: &mut ParserCore, radix: Radix, ) -> ParseResult<i128>
Read an integer from the stream at the current location and compute and return its value. Every alphanumeric character is treated as if it is part of the number. Underscores may be permitted in the number.
The number is parsed according to the given radix. Radix specifiers are not permitted.
Errors are generated if an unexpected alphanumeric character is encountered during parsing. The first non-alphanumeric stops the parse.
Sourcepub fn parse_u128_radix(
&self,
parser: &mut ParserCore,
radix: Radix,
) -> ParseResult<u128>
pub fn parse_u128_radix( &self, parser: &mut ParserCore, radix: Radix, ) -> ParseResult<u128>
Read an integer from the stream at the current location and compute and return its value. Every alphanumeric character is treated as if it is part of the number. Underscores may be permitted in the number.
The number is parsed according to the given radix. Radix specifiers are not permitted.
Errors are generated if an unexpected alphanumeric character is encountered during parsing. The first non-alphanumeric stops the parse.
Sourcepub fn parse_i64_radix(
&self,
parser: &mut ParserCore,
radix: Radix,
) -> ParseResult<i64>
pub fn parse_i64_radix( &self, parser: &mut ParserCore, radix: Radix, ) -> ParseResult<i64>
Read an integer from the stream at the current location and compute and return its value. Every alphanumeric character is treated as if it is part of the number. Underscores may be permitted in the number.
The number is parsed according to the given radix. Radix specifiers are not permitted.
Errors are generated if an unexpected alphanumeric character is encountered during parsing. The first non-alphanumeric stops the parse.
Sourcepub fn parse_u64_radix(
&self,
parser: &mut ParserCore,
radix: Radix,
) -> ParseResult<u64>
pub fn parse_u64_radix( &self, parser: &mut ParserCore, radix: Radix, ) -> ParseResult<u64>
Read an integer from the stream at the current location and compute and return its value. Every alphanumeric character is treated as if it is part of the number. Underscores may be permitted in the number.
The number is parsed according to the given radix. Radix specifiers are not permitted.
Errors are generated if an unexpected alphanumeric character is encountered during parsing. The first non-alphanumeric stops the parse.
Trait Implementations§
Source§impl Clone for NumberParser
impl Clone for NumberParser
Source§fn clone(&self) -> NumberParser
fn clone(&self) -> NumberParser
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read more