1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
/// Parses a type that impls [`ParserFor`] with the passed in [`Parser`]. /// /// # Example /// /// This example demonstrates how you can use this macro to parse both /// standard library and user-defined types. /// /// ```rust /// use konst::{parse_with, try_rebind, unwrap_ctx}; /// /// use konst::parsing::{ParserFor, Parser, ParseValueResult}; /// /// const PAIR: (u32, Foo) = unwrap_ctx!(parse_pair(Parser::from_str("100,Baz"))).0; /// /// assert_eq!(PAIR.0, 100); /// assert_eq!(PAIR.1, Foo::Baz); /// /// const fn parse_pair(mut parser: Parser<'_>) -> ParseValueResult<'_, (u32, Foo)> { /// try_rebind!{(let left, parser) = parse_with!(parser, u32)} /// try_rebind!{parser = parser.strip_prefix_u8(b',')} /// try_rebind!{(let right, parser) = parse_with!(parser, Foo)} /// /// Ok(((left, right), parser)) /// } /// /// /// #[derive(Debug, PartialEq)] /// enum Foo { /// Bar, /// Baz, /// Qux, /// } /// /// impl ParserFor for Foo { /// type Parser = Self; /// } /// /// impl Foo { /// const fn parse_with(parser: Parser<'_>) -> ParseValueResult<'_, Self> { /// // You can use the `parse_any` macro instead of this chain of if elses /// if let Ok(parser) = parser.strip_prefix("Bar") { /// Ok((Foo::Bar, parser)) /// } else if let Ok(parser) = parser.strip_prefix("Baz") { /// Ok((Foo::Baz, parser)) /// } else if let Ok(parser) = parser.strip_prefix("Qux") { /// Ok((Foo::Qux, parser)) /// } else { /// Err(parser.into_other_error()) /// } /// } /// } /// ``` /// /// [`Parser`]: ./parsing/struct.Parser.html /// [`ParserFor`]: ./parsing/trait.ParserFor.html #[macro_export] macro_rules! parse_with { ($parser:expr, $type:ty $(,)*) => { match $parser { parser @ $crate::Parser { .. } => { let res: $crate::__::Result<_, _> = <<$type as $crate::parsing::ParserFor>::Parser>::parse_with(parser); res } } }; }