Struct konst::parsing::Parser [−][src]
parsing_no_proc
only.For parsing and traversing over byte strings in const contexts.
If you’re looking for functions to parse some type from an entire string
(instead of only part of it),
then you want to look in the module for that type, eg: primitive::parse_bool
.
Mutation
Because konst
only requires Rust 1.46.0,
in order to mutate a parser you must reassign the parser returned by its methods.
eg: parser = parser.trim_start();
To help make this more ergonomic for Result
-returning methods, you can use these macros:
-
try_rebind
: Like the?
operator, but also reassigns variables with the value in theOk
variant. -
rebind_if_ok
: Like anif let Ok
, but also reassigns variables with the value in theOk
variant. -
parse_any
: Parses any of the string literal patterns using a supportedParser
method.
Examples
Parsing a variable-length array
Parses a variable-length array, requires the length to appear before the array.
This example requires the “parsing” feature (enabled by default)
because it uses the parse_any
macro.
use konst::{ parsing::{Parser, ParseValueResult}, for_range, parse_any, try_rebind, unwrap_ctx, }; // We need to parse the length into a separate const to use it as the length of the array. const LEN_AND_PARSER: (usize, Parser<'_>) = { let input = "\ 6; up, 0, 90, down, left, right, "; let parser = Parser::from_str(input); let (len, parser) = unwrap_ctx!(parser.parse_usize()); (len, unwrap_ctx!(parser.strip_prefix_u8(b';'))) }; const LEN: usize = LEN_AND_PARSER.0; const ANGLES: [Angle; LEN] = unwrap_ctx!(Angle::parse_array(LEN_AND_PARSER.1)).0; fn main() { assert_eq!( ANGLES, [Angle::UP, Angle::UP, Angle::RIGHT, Angle::DOWN, Angle::LEFT, Angle::RIGHT] ); } #[derive(Debug, PartialEq, Eq, Copy, Clone)] struct Angle(u16); impl Angle { pub const UP: Self = Self(0); pub const RIGHT: Self = Self(90); pub const DOWN: Self = Self(180); pub const LEFT: Self = Self(270); pub const fn new(n: u64) -> Angle { Angle((n % 360) as u16) } // This could take a `const LEN: usize` const parameter in Rust 1.51.0, // so that the returned array can be any length. const fn parse_array(mut parser: Parser<'_>) -> ParseValueResult<'_, [Angle; LEN]> { let mut ret = [Angle::UP; LEN]; for_range!{i in 0..LEN => try_rebind!{(ret[i], parser) = Angle::parse(parser.trim_start())} parser = parser.trim_start(); if !parser.is_empty() { try_rebind!{parser = parser.strip_prefix_u8(b',')} } } Ok((ret, parser)) } pub const fn parse(mut parser: Parser<'_>) -> ParseValueResult<'_, Angle> { // Prefer using the `rebind_if_ok` macro if you don't `return` inside the `if let`, // because the `parser` inside this `if let` is a different variable than outside. if let Ok((angle, parser)) = parser.parse_u64() { return Ok((Self::new(angle), parser)) } let angle = parse_any!{parser, strip_prefix; "up" => Self::UP, "right" => Self::RIGHT, "down" => Self::DOWN, "left" => Self::LEFT, _ => return Err(parser.into_other_error()) }; Ok((angle, parser)) } }
Implementations
impl<'a> Parser<'a>
[src]
pub const fn from_bytes(bytes: &'a [u8]) -> Self
[src]
Constructs a Parser from a byte string.
pub const fn from_str(string: &'a str) -> Self
[src]
Constructs a Parser from a string.
pub const fn bytes(self) -> &'a [u8]
[src]
Returns the remaining, unparsed bytes.
pub const fn start_offset(self) -> usize
[src]
Gets the byte offset of this parser in the str/byte slice that this was constructed from.
pub const fn end_offset(self) -> usize
[src]
Gets the end byte offset of this parser in the str/byte slice that this was constructed from.
pub fn parse_direction(&self) -> ParseDirection
[src]
The end the parser was last mutated from.
pub const fn into_error(self, kind: ErrorKind) -> ParseError<'a>
[src]
Constructs a ParseError
for this point in parsing.
pub const fn into_other_error(self) -> ParseError<'a>
[src]
Constructs a ParseError
for this point in parsing,
with an ErrorKind::Other
for the kind of error.
pub const fn advance_to_remainder_from_start(self, to: &'a [u8]) -> Self
[src]
Updates the unparsed bytes to to
, assuming that self.bytes().ends_with(to)
is true.
pub const fn advance_to_remainder_from_end(self, to: &'a [u8]) -> Self
[src]
Updates the unparsed bytes to to
, assuming that self.bytes().starts_with(to)
is true.
pub const fn len(self) -> usize
[src]
The amount of unparsed bytes.
pub const fn is_empty(self) -> bool
[src]
Whether there are any bytes left to parse.
impl<'a> Parser<'a>
[src]
pub const fn parse_u128(self) -> ParseValueResult<'a, u128>
[src]
Parses a u128
until a non-digit is reached.
To parse an integer from an entire string (erroring on non-digit bytes),
you can use primitive::parse_u128
Example
use konst::{ parsing::{Parser, ParseValueResult}, unwrap_ctx, try_rebind, }; { let parser = Parser::from_str("12345"); let (num, parser) = unwrap_ctx!(parser.parse_u128()); assert_eq!(num, 12345); assert!(parser.bytes().is_empty()); } /// Parses a `[u128; 2]` from a parser starting with `"<number>;<number>", eg: `"100;400"`. const fn parse_pair(mut parser: Parser<'_>) -> ParseValueResult<'_, [u128; 2]> { let mut ret = [0; 2]; // `try_rebind` is like the `?` operator, // and it assigns the value in the Ok variant into either a // single pre-existing variable or multiple (if the Ok value is a tuple) try_rebind!{(ret[0], parser) = parser.parse_u128()}; // parsing the `;``between the integers. // // Note that because we don't use `.trim_start()` afterwards, // this can't be followed by spaces. try_rebind!{parser = parser.strip_prefix(";")}; try_rebind!{(ret[1], parser) = parser.parse_u128()}; Ok((ret, parser)) } const PAIR: ([u128; 2], Parser<'_>) = { let parser = Parser::from_str("1365;6789"); unwrap_ctx!(parse_pair(parser)) }; assert_eq!(PAIR.0[0], 1365); assert_eq!(PAIR.0[1], 6789); assert!(PAIR.1.is_empty());
pub const fn parse_i128(self) -> ParseValueResult<'a, i128>
[src]
Parses a i128
until a non-digit is reached.
To parse an integer from an entire string (erroring on non-digit bytes),
you can use primitive::parse_i128
Example
use konst::{Parser, unwrap_ctx, rebind_if_ok}; { let parser = Parser::from_str("12345"); let (num, parser) = unwrap_ctx!(parser.parse_i128()); assert_eq!(num, 12345); assert!(parser.bytes().is_empty()); } { let mut num = 0; let mut parser = Parser::from_str("-54321;6789"); // `rebind_if_ok` stores the return value of `.parse_i128()` in `num` and `parser`, // if `.parse_i128()` returned an `Ok((u128, Parser))`. rebind_if_ok!{(num, parser) = parser.parse_i128()} assert_eq!(num, -54321); assert_eq!(parser.bytes(), b";6789"); rebind_if_ok!{parser = parser.strip_prefix(";")} assert_eq!(parser.bytes(), b"6789"); rebind_if_ok!{(num, parser) = parser.parse_i128()} assert_eq!(num, 6789); assert!(parser.is_empty()); }
pub const fn parse_u64(self) -> ParseValueResult<'a, u64>
[src]
Parses a u64
until a non-digit is reached.
To parse an integer from an entire string (erroring on non-digit bytes),
you can use primitive::parse_u64
Example
For an example for how to use this method,
you can look at the docs for the Parser::parse_u128
method.
pub const fn parse_i64(self) -> ParseValueResult<'a, i64>
[src]
Parses a i64
until a non-digit is reached.
To parse an integer from an entire string (erroring on non-digit bytes),
you can use primitive::parse_i64
Example
For an example for how to use this method,
you can look at the docs for the Parser::parse_i128
method.
pub const fn parse_u32(self) -> ParseValueResult<'a, u32>
[src]
Parses a u32
until a non-digit is reached.
To parse an integer from an entire string (erroring on non-digit bytes),
you can use primitive::parse_u32
Example
For an example for how to use this method,
you can look at the docs for the Parser::parse_u128
method.
pub const fn parse_i32(self) -> ParseValueResult<'a, i32>
[src]
Parses a i32
until a non-digit is reached.
To parse an integer from an entire string (erroring on non-digit bytes),
you can use primitive::parse_i32
Example
For an example for how to use this method,
you can look at the docs for the Parser::parse_i128
method.
pub const fn parse_u16(self) -> ParseValueResult<'a, u16>
[src]
Parses a u16
until a non-digit is reached.
To parse an integer from an entire string (erroring on non-digit bytes),
you can use primitive::parse_u16
Example
For an example for how to use this method,
you can look at the docs for the Parser::parse_u128
method.
pub const fn parse_i16(self) -> ParseValueResult<'a, i16>
[src]
Parses a i16
until a non-digit is reached.
To parse an integer from an entire string (erroring on non-digit bytes),
you can use primitive::parse_i16
Example
For an example for how to use this method,
you can look at the docs for the Parser::parse_i128
method.
pub const fn parse_u8(self) -> ParseValueResult<'a, u8>
[src]
Parses a u8
until a non-digit is reached.
To parse an integer from an entire string (erroring on non-digit bytes),
you can use primitive::parse_u8
Example
For an example for how to use this method,
you can look at the docs for the Parser::parse_u128
method.
pub const fn parse_i8(self) -> ParseValueResult<'a, i8>
[src]
Parses a i8
until a non-digit is reached.
To parse an integer from an entire string (erroring on non-digit bytes),
you can use primitive::parse_i8
Example
For an example for how to use this method,
you can look at the docs for the Parser::parse_i128
method.
pub const fn parse_usize(self) -> ParseValueResult<'a, usize>
[src]
Parses a usize
until a non-digit is reached.
To parse an integer from an entire string (erroring on non-digit bytes),
you can use primitive::parse_usize
pub const fn parse_isize(self) -> ParseValueResult<'a, isize>
[src]
Parses a isize
until a non-digit is reached.
To parse an integer from an entire string (erroring on non-digit bytes),
you can use primitive::parse_isize
Example
For an example for how to use this method,
you can look at the docs for the Parser::parse_i128
method.
impl<'a> Parser<'a>
[src]
pub const fn parse_bool(self) -> ParseValueResult<'a, bool>
[src]
Parses a bool
.
Example
use konst::{Parser, unwrap_ctx}; { let parser = Parser::from_str("falsemorestring"); let (boolean, parser) = unwrap_ctx!(parser.parse_bool()); assert_eq!(boolean, false); assert_eq!(parser.bytes(), "morestring".as_bytes()); } { let parser = Parser::from_str("truefoo"); let (boolean, parser) = unwrap_ctx!(parser.parse_bool()); assert_eq!(boolean, true); assert_eq!(parser.bytes(), "foo".as_bytes()); }
impl<'a> Parser<'a>
[src]
pub const fn next_byte(self) -> ParseValueResult<'a, u8>
[src]
Gets the next unparsed byte.
pub const fn skip(self, bytes: usize) -> Self
[src]
For skipping the first bytes
bytes.
Performance
If the “constant_time_slice” feature is disabled,
thich takes linear time to remove the leading elements,
proportional to bytes
.
If the “constant_time_slice” feature is enabled, it takes constant time to run, but uses a few nightly features.
pub const fn strip_prefix(self, matched: &str) -> Result<Self, ParseError<'a>>
[src]
Checks that the parsed bytes start with matched
,
returning the remainder of the bytes.
For calling strip_prefix
with multiple alternative matched
string literals,
you can use the parse_any
macro,
example
Examples
Basic
use konst::{Parser, rebind_if_ok}; let mut parser = Parser::from_str("foo;bar;baz;"); assert!(parser.strip_prefix("aaa").is_err()); rebind_if_ok!{parser = parser.strip_prefix("foo;")} assert_eq!(parser.bytes(), "bar;baz;".as_bytes()); rebind_if_ok!{parser = parser.strip_prefix("bar;")} assert_eq!(parser.bytes(), "baz;".as_bytes()); rebind_if_ok!{parser = parser.strip_prefix("baz;")} assert_eq!(parser.bytes(), "".as_bytes());
Use case
use konst::{Parser, rebind_if_ok}; #[derive(Debug, PartialEq)] struct Flags { foo: bool, bar: bool, } const fn parse_flags(mut parser: Parser<'_>) -> (Flags, Parser<'_>) { let mut flags = Flags{foo: false, bar: false}; rebind_if_ok!{parser = parser.strip_prefix("foo;") => flags.foo = true; } rebind_if_ok!{parser = parser.strip_prefix("bar;") => flags.bar = true; } (flags, parser) } const VALUES: &[Flags] = &[ parse_flags(Parser::from_str("")).0, parse_flags(Parser::from_str("foo;")).0, parse_flags(Parser::from_str("bar;")).0, parse_flags(Parser::from_str("foo;bar;")).0, ]; assert_eq!(VALUES[0], Flags{foo: false, bar: false}); assert_eq!(VALUES[1], Flags{foo: true, bar: false}); assert_eq!(VALUES[2], Flags{foo: false, bar: true}); assert_eq!(VALUES[3], Flags{foo: true, bar: true});
pub const fn strip_prefix_b(
self,
matched: &[u8]
) -> Result<Self, ParseError<'a>>
[src]
self,
matched: &[u8]
) -> Result<Self, ParseError<'a>>
Equivalent to strip_prefix
, but takes a byte slice.
pub const fn strip_prefix_u8(self, matched: u8) -> Result<Self, ParseError<'a>>
[src]
Equivalent to strip_prefix
, but takes a single byte.
Example
use konst::{Parser, rebind_if_ok}; let mut parser = Parser::from_str("abcde"); assert!(parser.strip_prefix_u8(1).is_err()); rebind_if_ok!{parser = parser.strip_prefix_u8(b'a')} assert_eq!(parser.bytes(), "bcde".as_bytes()); rebind_if_ok!{parser = parser.strip_prefix_u8(b'b')} assert_eq!(parser.bytes(), "cde".as_bytes()); rebind_if_ok!{parser = parser.strip_prefix_u8(b'c')} assert_eq!(parser.bytes(), "de".as_bytes());
pub const fn strip_suffix(self, matched: &str) -> Result<Self, ParseError<'a>>
[src]
Checks that the parsed bytes end with matched
,
returning the remainder of the bytes.
For calling strip_suffix
with multiple alternative matched
string literals,
you can use the parse_any
macro.
Examples
Basic
use konst::{Parser, rebind_if_ok}; let mut parser = Parser::from_str("foo;bar;baz;"); assert!(parser.strip_suffix("aaa").is_err()); rebind_if_ok!{parser = parser.strip_suffix("baz;")} assert_eq!(parser.bytes(), "foo;bar;".as_bytes()); rebind_if_ok!{parser = parser.strip_suffix("bar;")} assert_eq!(parser.bytes(), "foo;".as_bytes()); rebind_if_ok!{parser = parser.strip_suffix("foo;")} assert_eq!(parser.bytes(), "".as_bytes());
pub const fn strip_suffix_b(
self,
matched: &[u8]
) -> Result<Self, ParseError<'a>>
[src]
self,
matched: &[u8]
) -> Result<Self, ParseError<'a>>
Equivalent to strip_suffix
, but takes a byte slice.
pub const fn strip_suffix_u8(self, matched: u8) -> Result<Self, ParseError<'a>>
[src]
Equivalent to strip_suffix
, but takes a single byte.
Example
use konst::{Parser, rebind_if_ok}; let mut parser = Parser::from_str("edcba"); assert!(parser.strip_suffix_u8(1).is_err()); rebind_if_ok!{parser = parser.strip_suffix_u8(b'a')} assert_eq!(parser.bytes(), "edcb".as_bytes()); rebind_if_ok!{parser = parser.strip_suffix_u8(b'b')} assert_eq!(parser.bytes(), "edc".as_bytes()); rebind_if_ok!{parser = parser.strip_suffix_u8(b'c')} assert_eq!(parser.bytes(), "ed".as_bytes());
pub const fn trim_start(self) -> Self
[src]
Removes whitespace from the start of the parsed bytes.
Example
use konst::{Parser, unwrap_ctx}; let mut parser = Parser::from_str(" foo\n\t bar"); parser = parser.trim_start(); assert_eq!(parser.bytes(), "foo\n\t bar".as_bytes()); parser = unwrap_ctx!(parser.strip_prefix("foo")).trim_start(); assert_eq!(parser.bytes(), "bar".as_bytes());
pub const fn trim_end(self) -> Self
[src]
Removes whitespace from the end of the parsed bytes.
Example
use konst::{Parser, unwrap_ctx}; let mut parser = Parser::from_str("foo,\n bar,\n "); parser = parser.trim_end(); assert_eq!(parser.bytes(), "foo,\n bar,".as_bytes()); parser = unwrap_ctx!(parser.strip_suffix("bar,")).trim_end(); assert_eq!(parser.bytes(), "foo,".as_bytes());
pub const fn trim_start_matches(self, needle: &str) -> Self
[src]
Repeatedly removes all instances of needle
from the start of the parsed bytes.
For trimming with multiple needle
s, you can use the parse_any
macro,
example
Example
use konst::Parser; { let mut parser = Parser::from_str("HelloHelloHello world!"); parser = parser.trim_start_matches("Hello"); assert_eq!(parser.bytes(), " world!".as_bytes()); } { let mut parser = Parser::from_str(" Hi!"); parser = parser.trim_start_matches(" "); assert_eq!(parser.bytes(), "Hi!".as_bytes()); } { let mut parser = Parser::from_str("------Bye!"); parser = parser.trim_start_matches("----"); assert_eq!(parser.bytes(), "--Bye!".as_bytes()); }
pub const fn trim_start_matches_b(self, needle: &[u8]) -> Self
[src]
Equivalent to trim_start_matches
, but takes a byte slice.
pub const fn trim_start_matches_u8(self, needle: u8) -> Self
[src]
Equivalent to trim_start_matches
, but takes a single byte.
Example
use konst::Parser; let mut parser = Parser::from_str(" ----world"); parser = parser.trim_start_matches_u8(b' '); assert_eq!(parser.bytes(), "----world".as_bytes()); parser = parser.trim_start_matches_u8(b'-'); assert_eq!(parser.bytes(), "world".as_bytes()); parser = parser.trim_start_matches_u8(b'-'); assert_eq!(parser.bytes(), "world".as_bytes());
pub const fn trim_end_matches(self, needle: &str) -> Self
[src]
Repeatedly removes all instances of needle
from the start of the parsed bytes.
For trimming with multiple needle
s, you can use the parse_any
macro,
example
Example
use konst::Parser; { let mut parser = Parser::from_str("Hello world!world!world!"); parser = parser.trim_end_matches("world!"); assert_eq!(parser.bytes(), "Hello ".as_bytes()); } { let mut parser = Parser::from_str("Hi! "); parser = parser.trim_end_matches(" "); assert_eq!(parser.bytes(), "Hi!".as_bytes()); } { let mut parser = Parser::from_str("Bye!------"); parser = parser.trim_end_matches("----"); assert_eq!(parser.bytes(), "Bye!--".as_bytes()); }
pub const fn trim_end_matches_b(self, needle: &[u8]) -> Self
[src]
Equivalent to trim_end_matches
, but takes a byte slice.
pub const fn trim_end_matches_u8(self, needle: u8) -> Self
[src]
Equivalent to trim_end_matches
, but takes a single byte.
Example
use konst::Parser; let mut parser = Parser::from_str("world---- "); parser = parser.trim_end_matches_u8(b' '); assert_eq!(parser.bytes(), "world----".as_bytes()); parser = parser.trim_end_matches_u8(b'-'); assert_eq!(parser.bytes(), "world".as_bytes()); parser = parser.trim_end_matches_u8(b'-'); assert_eq!(parser.bytes(), "world".as_bytes());
pub const fn find_skip(self, needle: &str) -> Result<Self, ParseError<'a>>
[src]
Skips the parser after the first instance of needle
.
For calling find_skip
with multiple alternative ǹeedle
string literals,
you can use the parse_any
macro,
example
Example
use konst::{Parser, unwrap_ctx}; let mut parser = Parser::from_str("foo--bar,baz--qux"); parser = unwrap_ctx!(parser.find_skip("--")); assert_eq!(parser.bytes(), "bar,baz--qux".as_bytes()); parser = unwrap_ctx!(parser.find_skip("bar,")); assert_eq!(parser.bytes(), "baz--qux".as_bytes()); parser = unwrap_ctx!(parser.find_skip("--")); assert_eq!(parser.bytes(), "qux".as_bytes()); assert!(parser.find_skip("--").is_err());
pub const fn find_skip_b(self, needle: &[u8]) -> Result<Self, ParseError<'a>>
[src]
Equivalent to find_skip
, but takes a byte slice.
pub const fn find_skip_u8(self, needle: u8) -> Result<Self, ParseError<'a>>
[src]
Equivalent to find_skip
, but takes a single byte.
Example
use konst::{Parser, unwrap_ctx}; let mut parser = Parser::from_str("foo-bar,baz"); parser = unwrap_ctx!(parser.find_skip_u8(b'-')); assert_eq!(parser.bytes(), "bar,baz".as_bytes()); parser = unwrap_ctx!(parser.find_skip_u8(b',')); assert_eq!(parser.bytes(), "baz".as_bytes());
pub const fn rfind_skip(self, needle: &str) -> Result<Self, ParseError<'a>>
[src]
Truncates the parsed bytes to before the last instance of needle
.
For calling find_skip
with multiple alternative ǹeedle
string literals,
you can use the parse_any
macro,
example
Example
use konst::{Parser, unwrap_ctx}; let mut parser = Parser::from_str("foo--bar,baz--qux"); parser = unwrap_ctx!(parser.rfind_skip("--")); assert_eq!(parser.bytes(), "foo--bar,baz".as_bytes()); parser = unwrap_ctx!(parser.rfind_skip(",baz")); assert_eq!(parser.bytes(), "foo--bar".as_bytes()); parser = unwrap_ctx!(parser.rfind_skip("--")); assert_eq!(parser.bytes(), "foo".as_bytes()); assert!(parser.rfind_skip("--").is_err());
pub const fn rfind_skip_b(self, needle: &[u8]) -> Result<Self, ParseError<'a>>
[src]
Equivalent to find_skip
, but takes a byte slice.
pub const fn rfind_skip_u8(self, needle: u8) -> Result<Self, ParseError<'a>>
[src]
Equivalent to find_skip
, but takes a single byte.
Example
use konst::{Parser, unwrap_ctx}; let mut parser = Parser::from_str("foo,bar-baz"); parser = unwrap_ctx!(parser.rfind_skip_u8(b'-')); assert_eq!(parser.bytes(), "foo,bar".as_bytes()); parser = unwrap_ctx!(parser.rfind_skip_u8(b',')); assert_eq!(parser.bytes(), "foo".as_bytes());
Trait Implementations
impl<'a> Clone for Parser<'a>
[src]
fn clone(&self) -> Parser<'a>
[src]
pub fn clone_from(&mut self, source: &Self)
1.0.0[src]
impl<'a> Copy for Parser<'a>
[src]
impl<'a> Debug for Parser<'a>
[src]
impl<'a> Eq for Parser<'a>
[src]
impl<'a> PartialEq<Parser<'a>> for Parser<'a>
[src]
impl<'a> StructuralEq for Parser<'a>
[src]
impl<'a> StructuralPartialEq for Parser<'a>
[src]
Auto Trait Implementations
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,