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}