1use crate::{SolPath, Spanned, Type, kw};
2use proc_macro2::Span;
3use std::fmt;
4use syn::{
5 Result, Token, braced,
6 parse::{Parse, ParseStream},
7 punctuated::Punctuated,
8 token::Brace,
9};
10
11#[derive(Clone)]
16pub struct UsingDirective {
17 pub using_token: kw::using,
18 pub list: UsingList,
19 pub for_token: Token![for],
20 pub ty: UsingType,
21 pub global_token: Option<kw::global>,
22 pub semi_token: Token![;],
23}
24
25impl fmt::Display for UsingDirective {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 write!(
28 f,
29 "using {} for {}{};",
30 self.list,
31 self.ty,
32 if self.global_token.is_some() { " global" } else { "" }
33 )
34 }
35}
36
37impl fmt::Debug for UsingDirective {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 f.debug_struct("UsingDirective")
40 .field("list", &self.list)
41 .field("ty", &self.ty)
42 .field("global", &self.global_token.is_some())
43 .finish()
44 }
45}
46
47impl Parse for UsingDirective {
48 fn parse(input: ParseStream<'_>) -> Result<Self> {
49 Ok(Self {
50 using_token: input.parse()?,
51 list: input.parse()?,
52 for_token: input.parse()?,
53 ty: input.parse()?,
54 global_token: input.parse()?,
55 semi_token: input.parse()?,
56 })
57 }
58}
59
60impl Spanned for UsingDirective {
61 fn span(&self) -> Span {
62 let span = self.using_token.span;
63 span.join(self.semi_token.span).unwrap_or(span)
64 }
65
66 fn set_span(&mut self, span: Span) {
67 self.using_token.span = span;
68 self.semi_token.span = span;
69 }
70}
71
72#[derive(Clone, Debug)]
73pub enum UsingList {
74 Single(SolPath),
75 Multiple(Brace, Punctuated<UsingListItem, Token![,]>),
76}
77
78impl fmt::Display for UsingList {
79 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80 match self {
81 Self::Single(path) => path.fmt(f),
82 Self::Multiple(_, list) => {
83 f.write_str("{")?;
84 for (i, item) in list.iter().enumerate() {
85 if i > 0 {
86 f.write_str(", ")?;
87 }
88 item.fmt(f)?;
89 }
90 f.write_str("}")
91 }
92 }
93 }
94}
95
96impl Parse for UsingList {
97 fn parse(input: ParseStream<'_>) -> Result<Self> {
98 if input.peek(Brace) {
99 let content;
100 Ok(Self::Multiple(
101 braced!(content in input),
102 content.parse_terminated(UsingListItem::parse, Token![,])?,
103 ))
104 } else {
105 input.parse().map(Self::Single)
106 }
107 }
108}
109
110impl Spanned for UsingList {
111 fn span(&self) -> Span {
112 match self {
113 Self::Single(path) => path.span(),
114 Self::Multiple(brace, list) => {
115 let span = brace.span.join();
116 span.join(list.span()).unwrap_or(span)
117 }
118 }
119 }
120
121 fn set_span(&mut self, span: Span) {
122 match self {
123 Self::Single(path) => path.set_span(span),
124 Self::Multiple(brace, list) => {
125 *brace = Brace(span);
126 list.set_span(span);
127 }
128 }
129 }
130}
131
132#[derive(Clone, Debug)]
133pub struct UsingListItem {
134 pub path: SolPath,
135 pub op: Option<(Token![as], UserDefinableOperator)>,
136}
137
138impl fmt::Display for UsingListItem {
139 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
140 self.path.fmt(f)?;
141 if let Some((_, op)) = &self.op {
142 write!(f, " as {op}")?;
143 }
144 Ok(())
145 }
146}
147
148impl Parse for UsingListItem {
149 fn parse(input: ParseStream<'_>) -> Result<Self> {
150 Ok(Self {
151 path: input.parse()?,
152 op: if input.peek(Token![as]) { Some((input.parse()?, input.parse()?)) } else { None },
153 })
154 }
155}
156
157impl Spanned for UsingListItem {
158 fn span(&self) -> Span {
159 self.path.span()
160 }
161
162 fn set_span(&mut self, span: Span) {
163 self.path.set_span(span);
164 }
165}
166
167#[derive(Clone, Debug)]
168pub enum UsingType {
169 Star(Token![*]),
170 Type(Type),
171}
172
173impl fmt::Display for UsingType {
174 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
175 match self {
176 Self::Star(_) => f.write_str("*"),
177 Self::Type(ty) => ty.fmt(f),
178 }
179 }
180}
181
182impl Parse for UsingType {
183 fn parse(input: ParseStream<'_>) -> Result<Self> {
184 if input.peek(Token![*]) {
185 input.parse().map(Self::Star)
186 } else {
187 input.parse().map(Self::Type)
188 }
189 }
190}
191
192impl Spanned for UsingType {
193 fn span(&self) -> Span {
194 match self {
195 Self::Star(star) => star.span,
196 Self::Type(ty) => ty.span(),
197 }
198 }
199
200 fn set_span(&mut self, span: Span) {
201 match self {
202 Self::Star(star) => star.span = span,
203 Self::Type(ty) => ty.set_span(span),
204 }
205 }
206}
207
208op_enum! {
209 pub enum UserDefinableOperator {
214 BitAnd(&),
215 BitNot(~),
216 BitOr(|),
217 BitXor(^),
218 Add(+),
219 Div(/),
220 Rem(%),
221 Mul(*),
222 Sub(-),
223 Eq(==),
224 Ge(>=),
225 Gt(>),
226 Le(<=),
227 Lt(<),
228 Ne(!=),
229 }
230}