rune/parse/
parse.rs

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
68
69
use crate::alloc::{Box, Vec};
use crate::compile;
use crate::parse::{Parser, Peek};

/// Helper derive to implement [`Parse`].
pub use rune_macros::Parse;

/// The parse trait, implemented by items that can be parsed.
pub trait Parse
where
    Self: Sized,
{
    /// Parse the current item from the parser.
    fn parse(p: &mut Parser<'_>) -> compile::Result<Self>;
}

impl<A, B> Parse for (A, B)
where
    A: Parse + Peek,
    B: Parse,
{
    #[inline]
    fn parse(parser: &mut Parser<'_>) -> compile::Result<Self> {
        Ok((parser.parse()?, parser.parse()?))
    }
}

/// Parse implementation for something that can be optionally parsed.
impl<T> Parse for Option<T>
where
    T: Parse + Peek,
{
    #[inline]
    fn parse(parser: &mut Parser<'_>) -> compile::Result<Self> {
        Ok(if parser.peek::<T>()? {
            Some(parser.parse()?)
        } else {
            None
        })
    }
}

/// Parse implementation for something that is boxed.
impl<T> Parse for Box<T>
where
    T: Parse,
{
    #[inline]
    fn parse(parser: &mut Parser<'_>) -> compile::Result<Self> {
        Ok(Box::try_new(parser.parse()?)?)
    }
}

/// Parser implementation for a vector.
impl<T> Parse for Vec<T>
where
    T: Parse + Peek,
{
    #[inline]
    fn parse(parser: &mut Parser<'_>) -> compile::Result<Self> {
        let mut output = Vec::new();

        while parser.peek::<T>()? {
            output.try_push(parser.parse()?)?;
        }

        Ok(output)
    }
}