loess_rust/expressions/
literals.rs1use loess::{Error, ErrorPriority, Errors, Input, IntoTokens, PeekFrom, PopFrom, grammar};
2use proc_macro2::{Literal, TokenTree};
3
4grammar! {
5 #[derive(Clone)]
10 pub struct StringLiteral(pub Literal);
11
12 #[derive(Clone)]
17 pub struct RawStringLiteral(pub Literal);
18
19 #[derive(Clone)]
20 pub enum AnyStringLiteral: doc, PeekFrom, PopFrom, IntoTokens {
21 Plain(StringLiteral),
23 Raw(RawStringLiteral),
25 } else "Expected &str literal.";
26}
27
28impl PeekFrom for StringLiteral {
29 fn peek_from(input: &Input) -> bool {
30 matches!(input.front(), Some(TokenTree::Literal(literal)) if literal.to_string().starts_with('"'))
31 }
32}
33
34impl PopFrom for StringLiteral {
35 fn pop_from(input: &mut Input, errors: &mut Errors) -> Result<Self, ()> {
36 input
37 .pop_or_replace(|t, _| match t {
38 [TokenTree::Literal(literal)] if literal.to_string().starts_with('"') => {
39 Ok(Self(literal))
40 }
41 other => Err(other),
42 })
43 .map_err(|spans| {
44 errors.push(Error::new(ErrorPriority::GRAMMAR, "Expected `\"`.", spans))
45 })
46 }
47}
48
49impl IntoTokens for StringLiteral {
50 fn into_tokens(
51 self,
52 root: &proc_macro2::TokenStream,
53 tokens: &mut impl Extend<proc_macro2::TokenTree>,
54 ) {
55 self.0.into_tokens(root, tokens);
56 }
57}
58
59impl PeekFrom for RawStringLiteral {
60 fn peek_from(input: &Input) -> bool {
61 matches!(input.front(), Some(TokenTree::Literal(literal)) if literal.to_string().starts_with('r'))
63 }
64}
65
66impl PopFrom for RawStringLiteral {
67 fn pop_from(input: &mut Input, errors: &mut Errors) -> Result<Self, ()> {
68 input
69 .pop_or_replace(|t, _| match t {
70 [TokenTree::Literal(literal)] if literal.to_string().starts_with('r') => {
71 Ok(Self(literal))
72 }
73 other => Err(other),
74 })
75 .map_err(|spans| {
76 errors.push(Error::new(
77 ErrorPriority::GRAMMAR,
78 "Expected raw string literal.",
79 spans,
80 ))
81 })
82 }
83}
84
85impl IntoTokens for RawStringLiteral {
86 fn into_tokens(
87 self,
88 root: &proc_macro2::TokenStream,
89 tokens: &mut impl Extend<proc_macro2::TokenTree>,
90 ) {
91 self.0.into_tokens(root, tokens);
92 }
93}