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