1use crate::{kw, Spanned};
2use proc_macro2::Span;
3use std::{
4 fmt,
5 ops::{Deref, DerefMut},
6};
7use syn::{
8 parse::{Lookahead1, Parse, ParseStream},
9 Result,
10};
11
12macro_rules! str_lit {
13 ($(#[$attr:meta])* $vis:vis struct $name:ident($t:ty) $(: $kw:ident)?) => {
14 #[derive(Clone, Debug)]
15 $vis struct $name {
16 $vis values: Vec<$t>,
17 }
18
19 impl fmt::Display for $name {
20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21 for (i, value) in self.values.iter().enumerate() {
22 if i > 0 {
23 f.write_str(" ")?;
24 }
25
26 $(
27 f.write_str(stringify!($kw))?;
28 )?
29 f.write_str(&value.value())?;
30 }
31 Ok(())
32 }
33 }
34
35 impl Parse for $name {
36 fn parse(input: ParseStream<'_>) -> Result<Self> {
37 let mut values = Vec::new();
38 let mut first = true;
39 while first || Self::peek(&input.lookahead1()) {
40 first = false;
41 values.push(input.parse()?);
42 }
43 Ok(Self { values })
44 }
45 }
46
47 impl Spanned for $name {
48 fn span(&self) -> Span {
49 self.values.span()
50 }
51
52 fn set_span(&mut self, span: Span) {
53 self.values.set_span(span);
54 }
55 }
56
57 impl $name {
58 pub fn peek(lookahead: &Lookahead1<'_>) -> bool {
59 $(lookahead.peek(kw::$kw) || )? lookahead.peek(syn::LitStr)
60 }
61
62 pub fn parse_opt(input: ParseStream<'_>) -> Result<Option<Self>> {
63 if Self::peek(&input.lookahead1()) {
64 input.parse().map(Some)
65 } else {
66 Ok(None)
67 }
68 }
69
70 pub fn value(&self) -> String {
71 self.values.iter().map(|v| v.value()).collect()
72 }
73 }
74 };
75}
76
77macro_rules! wrap_str {
78 ($(#[$attr:meta])* $vis:vis struct $name:ident { $token:ident : kw::$kw:ident $(,)? }) => {
79 $(#[$attr])*
80 #[derive(Clone)]
81 $vis struct $name {
82 $vis $token: kw::$kw,
84 $vis value: syn::LitStr,
86 }
87
88 impl fmt::Debug for $name {
89 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 f.debug_struct(stringify!($name))
91 .field("value", &self.value)
92 .finish()
93 }
94 }
95
96 impl Deref for $name {
97 type Target = syn::LitStr;
98
99 #[inline]
100 fn deref(&self) -> &Self::Target {
101 &self.value
102 }
103 }
104
105 impl DerefMut for $name {
106 #[inline]
107 fn deref_mut(&mut self) -> &mut Self::Target {
108 &mut self.value
109 }
110 }
111
112 impl Parse for $name {
113 fn parse(input: ParseStream<'_>) -> Result<Self> {
114 Ok(Self {
115 $token: input.parse()?,
116 value: input.parse()?,
117 })
118 }
119 }
120
121 impl Spanned for $name {
122 fn span(&self) -> Span {
123 let span = self.$token.span;
124 span.join(self.value.span()).unwrap_or(span)
125 }
126
127 fn set_span(&mut self, span: Span) {
128 self.$token.span = span;
129 self.value.set_span(span);
130 }
131 }
132 };
133}
134
135str_lit! {
136 pub struct LitStr(syn::LitStr)
138}
139
140str_lit! {
141 pub struct LitUnicodeStr(UnicodeStr): unicode
143}
144
145wrap_str! {
146 pub struct UnicodeStr {
148 unicode_token: kw::unicode,
149 }
150}
151
152str_lit! {
153 pub struct LitHexStr(HexStr): hex
155}
156
157wrap_str! {
158 pub struct HexStr {
160 hex_token: kw::hex,
161 }
162}