1 use std::fmt;
2 use std::iter;
3 
4 /// Valid Rust identifier
5 #[derive(Eq, PartialEq, Debug, Clone)]
6 pub(crate) struct RustIdent(String);
7 
8 #[allow(dead_code)]
9 impl RustIdent {
new(s: &str) -> RustIdent10     pub fn new(s: &str) -> RustIdent {
11         assert!(!s.is_empty());
12         assert!(!s.contains("/"), "{}", s);
13         assert!(!s.contains("."), "{}", s);
14         assert!(!s.contains(":"), "{}", s);
15         RustIdent(s.to_owned())
16     }
17 
super_ident() -> RustIdent18     pub fn super_ident() -> RustIdent {
19         RustIdent::new("super")
20     }
21 
get(&self) -> &str22     pub fn get(&self) -> &str {
23         &self.0
24     }
25 
into_string(self) -> String26     pub fn into_string(self) -> String {
27         self.0
28     }
29 
to_path(&self) -> RustIdentWithPath30     pub fn to_path(&self) -> RustIdentWithPath {
31         RustIdentWithPath::from(&self.0)
32     }
33 }
34 
35 impl fmt::Display for RustIdent {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result36     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
37         fmt::Display::fmt(&self.get(), f)
38     }
39 }
40 
41 impl From<&'_ str> for RustIdent {
from(s: &str) -> Self42     fn from(s: &str) -> Self {
43         RustIdent::new(s)
44     }
45 }
46 
47 impl From<String> for RustIdent {
from(s: String) -> Self48     fn from(s: String) -> Self {
49         RustIdent::new(&s)
50     }
51 }
52 
53 impl Into<String> for RustIdent {
into(self) -> String54     fn into(self) -> String {
55         self.0
56     }
57 }
58 
59 #[derive(Default, Eq, PartialEq, Debug, Clone)]
60 pub(crate) struct RustRelativePath {
61     path: Vec<RustIdent>,
62 }
63 
64 #[allow(dead_code)]
65 impl RustRelativePath {
into_path(self) -> RustPath66     pub fn into_path(self) -> RustPath {
67         RustPath {
68             absolute: false,
69             path: self,
70         }
71     }
72 
empty() -> RustRelativePath73     pub fn empty() -> RustRelativePath {
74         RustRelativePath { path: Vec::new() }
75     }
76 
from_components<I: IntoIterator<Item = RustIdent>>(i: I) -> RustRelativePath77     pub fn from_components<I: IntoIterator<Item = RustIdent>>(i: I) -> RustRelativePath {
78         RustRelativePath {
79             path: i.into_iter().collect(),
80         }
81     }
82 
is_empty(&self) -> bool83     pub fn is_empty(&self) -> bool {
84         self.path.is_empty()
85     }
86 
first(&self) -> Option<RustIdent>87     pub fn first(&self) -> Option<RustIdent> {
88         self.path.iter().cloned().next()
89     }
90 
remove_first(&mut self) -> Option<RustIdent>91     pub fn remove_first(&mut self) -> Option<RustIdent> {
92         if self.path.is_empty() {
93             None
94         } else {
95             Some(self.path.remove(0))
96         }
97     }
98 
prepend_ident(&mut self, ident: RustIdent)99     pub fn prepend_ident(&mut self, ident: RustIdent) {
100         self.path.insert(0, ident);
101     }
102 
append(mut self, path: RustRelativePath) -> RustRelativePath103     pub fn append(mut self, path: RustRelativePath) -> RustRelativePath {
104         for c in path.path {
105             self.path.push(c);
106         }
107         self
108     }
109 
push_ident(&mut self, ident: RustIdent)110     pub fn push_ident(&mut self, ident: RustIdent) {
111         self.path.push(ident);
112     }
113 
_append_ident(mut self, ident: RustIdent) -> RustRelativePath114     pub fn _append_ident(mut self, ident: RustIdent) -> RustRelativePath {
115         self.push_ident(ident);
116         self
117     }
118 
to_reverse(&self) -> RustRelativePath119     pub fn to_reverse(&self) -> RustRelativePath {
120         RustRelativePath::from_components(
121             iter::repeat(RustIdent::super_ident()).take(self.path.len()),
122         )
123     }
124 }
125 
126 #[derive(Default, Eq, PartialEq, Debug, Clone)]
127 pub(crate) struct RustPath {
128     absolute: bool,
129     path: RustRelativePath,
130 }
131 
132 impl fmt::Display for RustRelativePath {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result133     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
134         for (i, c) in self.path.iter().enumerate() {
135             if i != 0 {
136                 write!(f, "::")?;
137             }
138             write!(f, "{}", c)?;
139         }
140         Ok(())
141     }
142 }
143 
144 impl From<&'_ str> for RustRelativePath {
from(s: &str) -> Self145     fn from(s: &str) -> Self {
146         RustRelativePath {
147             path: s.split("::").map(RustIdent::from).collect(),
148         }
149     }
150 }
151 
152 #[allow(dead_code)]
153 impl RustPath {
is_absolute(&self) -> bool154     pub fn is_absolute(&self) -> bool {
155         self.absolute
156     }
157 
is_empty(&self) -> bool158     pub fn is_empty(&self) -> bool {
159         assert!(!self.absolute);
160         self.path.is_empty()
161     }
162 
with_ident(self, ident: RustIdent) -> RustIdentWithPath163     pub fn with_ident(self, ident: RustIdent) -> RustIdentWithPath {
164         RustIdentWithPath { path: self, ident }
165     }
166 
first(&self) -> Option<RustIdent>167     pub fn first(&self) -> Option<RustIdent> {
168         assert!(!self.absolute);
169         self.path.first()
170     }
171 
remove_first(&mut self) -> Option<RustIdent>172     pub fn remove_first(&mut self) -> Option<RustIdent> {
173         assert!(!self.absolute);
174         self.path.remove_first()
175     }
176 
to_reverse(&self) -> RustPath177     pub fn to_reverse(&self) -> RustPath {
178         assert!(!self.absolute);
179         RustPath {
180             absolute: false,
181             path: self.path.to_reverse(),
182         }
183     }
184 
prepend_ident(&mut self, ident: RustIdent)185     pub fn prepend_ident(&mut self, ident: RustIdent) {
186         assert!(!self.absolute);
187         self.path.prepend_ident(ident);
188     }
189 
append(self, path: RustPath) -> RustPath190     pub fn append(self, path: RustPath) -> RustPath {
191         if path.absolute {
192             path
193         } else {
194             RustPath {
195                 absolute: self.absolute,
196                 path: self.path.append(path.path),
197             }
198         }
199     }
200 
append_ident(mut self, ident: RustIdent) -> RustPath201     pub fn append_ident(mut self, ident: RustIdent) -> RustPath {
202         self.path.path.push(ident);
203         self
204     }
205 
append_with_ident(self, path: RustIdentWithPath) -> RustIdentWithPath206     pub fn append_with_ident(self, path: RustIdentWithPath) -> RustIdentWithPath {
207         self.append(path.path).with_ident(path.ident)
208     }
209 }
210 
211 impl From<&'_ str> for RustPath {
from(s: &str) -> Self212     fn from(s: &str) -> Self {
213         let (s, absolute) = if s.starts_with("::") {
214             (&s[2..], true)
215         } else {
216             (s, false)
217         };
218         RustPath {
219             absolute,
220             path: RustRelativePath::from(s),
221         }
222     }
223 }
224 
225 impl From<String> for RustPath {
from(s: String) -> Self226     fn from(s: String) -> Self {
227         RustPath::from(&s[..])
228     }
229 }
230 
231 impl fmt::Display for RustPath {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result232     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
233         if self.absolute {
234             write!(f, "::")?;
235         }
236         write!(f, "{}", self.path)
237     }
238 }
239 
240 #[derive(Eq, PartialEq, Debug, Clone)]
241 pub(crate) struct RustIdentWithPath {
242     pub path: RustPath,
243     pub ident: RustIdent,
244 }
245 
246 #[allow(dead_code)]
247 impl RustIdentWithPath {
new(s: String) -> RustIdentWithPath248     pub fn new(s: String) -> RustIdentWithPath {
249         let mut path = RustPath::from(s);
250         let ident = path.path.path.pop().unwrap();
251         RustIdentWithPath { path, ident }
252     }
253 
prepend_ident(&mut self, ident: RustIdent)254     pub fn prepend_ident(&mut self, ident: RustIdent) {
255         self.path.prepend_ident(ident)
256     }
257 
to_path(&self) -> RustPath258     pub fn to_path(&self) -> RustPath {
259         self.path.clone().append_ident(self.ident.clone())
260     }
261 }
262 
263 impl<S: Into<String>> From<S> for RustIdentWithPath {
from(s: S) -> Self264     fn from(s: S) -> Self {
265         RustIdentWithPath::new(s.into())
266     }
267 }
268 
269 impl fmt::Display for RustIdentWithPath {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result270     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
271         fmt::Display::fmt(&self.to_path(), f)
272     }
273 }
274