rune/ast/
lit.rs

1use crate::ast::prelude::*;
2
3#[test]
4#[cfg(not(miri))]
5fn ast_parse() {
6    rt::<ast::Lit>("true");
7    rt::<ast::Lit>("false");
8    rt::<ast::Lit>("'🔥'");
9    rt::<ast::Lit>("b'4'");
10    rt::<ast::Lit>("b\"bytes\"");
11    rt::<ast::Lit>("1.2");
12    rt::<ast::Lit>("42");
13    rt::<ast::Lit>("\"mary had a little lamb\"");
14}
15
16/// A literal value,
17///
18/// These are made available by parsing Rune. Custom literals for macros can be
19/// constructed through [MacroContext::lit][crate::macros::MacroContext::lit].
20///
21/// # Examples
22///
23/// Constructing a literal value:
24///
25/// ```
26/// use rune::ast;
27/// use rune::macros;
28///
29/// macros::test(|cx| {
30///     let lit = cx.lit("hello world")?;
31///     assert!(matches!(lit, ast::Lit::Str(..)));
32///     Ok(())
33/// })?;
34/// # Ok::<_, rune::support::Error>(())
35/// ```
36#[derive(Debug, TryClone, Clone, Copy, PartialEq, Eq, ToTokens, Spanned)]
37#[try_clone(copy)]
38#[non_exhaustive]
39pub enum Lit {
40    /// A boolean literal
41    Bool(ast::LitBool),
42    /// A byte literal
43    Byte(ast::LitByte),
44    /// A string literal
45    Str(ast::LitStr),
46    /// A byte string literal
47    ByteStr(ast::LitByteStr),
48    /// A character literal
49    Char(ast::LitChar),
50    /// A number literal
51    Number(ast::LitNumber),
52}
53
54impl Lit {
55    /// Test if this is an immediate literal in an expression.
56    ///
57    /// Here we only test for unambiguous literals which will not be caused by
58    /// a later stage as an expression is being parsed.
59    ///
60    /// These include:
61    /// * Object literals that start with a path (handled in [ast::Expr::parse_with_meta_path]).
62    /// * Tuple literals that start with a path (handled in [ast::Expr::parse_open_paren]).
63    pub(crate) fn peek_in_expr(p: &mut Peeker<'_>) -> bool {
64        match p.nth(0) {
65            K![true] | K![false] => true,
66            K![byte] => true,
67            K![number] => true,
68            K![char] => true,
69            K![str] => true,
70            K![bytestr] => true,
71            _ => false,
72        }
73    }
74}
75
76impl Parse for Lit {
77    fn parse(p: &mut Parser<'_>) -> Result<Self> {
78        match p.nth(0)? {
79            K![true] | K![false] => return Ok(Lit::Bool(p.parse()?)),
80            K![byte(_)] => return Ok(Lit::Byte(p.parse()?)),
81            K![number(_)] => return Ok(Lit::Number(p.parse()?)),
82            K![char(_)] => return Ok(Lit::Char(p.parse()?)),
83            K![str(_)] => return Ok(Lit::Str(p.parse()?)),
84            K![bytestr(_)] => return Ok(Lit::ByteStr(p.parse()?)),
85            _ => (),
86        }
87
88        Err(compile::Error::expected(p.next()?, Expectation::Literal))
89    }
90}