blob: 234925b44e03bad7f1502e6f4aebe5098d201708 [file] [log] [blame]
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -07001use std::fmt;
2use std::iter;
3
4/// Valid Rust identifier
5#[derive(Eq, PartialEq, Debug, Clone)]
6pub(crate) struct RustIdent(String);
7
8#[allow(dead_code)]
9impl RustIdent {
10 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
18 pub fn super_ident() -> RustIdent {
19 RustIdent::new("super")
20 }
21
22 pub fn get(&self) -> &str {
23 &self.0
24 }
25
26 pub fn into_string(self) -> String {
27 self.0
28 }
29
30 pub fn to_path(&self) -> RustIdentWithPath {
31 RustIdentWithPath::from(&self.0)
32 }
33}
34
35impl fmt::Display for RustIdent {
36 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
37 fmt::Display::fmt(&self.get(), f)
38 }
39}
40
41impl From<&'_ str> for RustIdent {
42 fn from(s: &str) -> Self {
43 RustIdent::new(s)
44 }
45}
46
47impl From<String> for RustIdent {
48 fn from(s: String) -> Self {
49 RustIdent::new(&s)
50 }
51}
52
53impl Into<String> for RustIdent {
54 fn into(self) -> String {
55 self.0
56 }
57}
58
59#[derive(Default, Eq, PartialEq, Debug, Clone)]
60pub(crate) struct RustRelativePath {
61 path: Vec<RustIdent>,
62}
63
64#[allow(dead_code)]
65impl RustRelativePath {
66 pub fn into_path(self) -> RustPath {
67 RustPath {
68 absolute: false,
69 path: self,
70 }
71 }
72
73 pub fn empty() -> RustRelativePath {
74 RustRelativePath { path: Vec::new() }
75 }
76
77 pub fn from_components<I: IntoIterator<Item = RustIdent>>(i: I) -> RustRelativePath {
78 RustRelativePath {
79 path: i.into_iter().collect(),
80 }
81 }
82
83 pub fn is_empty(&self) -> bool {
84 self.path.is_empty()
85 }
86
87 pub fn first(&self) -> Option<RustIdent> {
88 self.path.iter().cloned().next()
89 }
90
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
99 pub fn prepend_ident(&mut self, ident: RustIdent) {
100 self.path.insert(0, ident);
101 }
102
103 pub fn append(mut self, path: RustRelativePath) -> RustRelativePath {
104 for c in path.path {
105 self.path.push(c);
106 }
107 self
108 }
109
110 pub fn push_ident(&mut self, ident: RustIdent) {
111 self.path.push(ident);
112 }
113
114 pub fn _append_ident(mut self, ident: RustIdent) -> RustRelativePath {
115 self.push_ident(ident);
116 self
117 }
118
119 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)]
127pub(crate) struct RustPath {
128 absolute: bool,
129 path: RustRelativePath,
130}
131
132impl fmt::Display for RustRelativePath {
133 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
144impl From<&'_ str> for RustRelativePath {
145 fn from(s: &str) -> Self {
146 RustRelativePath {
147 path: s.split("::").map(RustIdent::from).collect(),
148 }
149 }
150}
151
152#[allow(dead_code)]
153impl RustPath {
154 pub fn is_absolute(&self) -> bool {
155 self.absolute
156 }
157
158 pub fn is_empty(&self) -> bool {
159 assert!(!self.absolute);
160 self.path.is_empty()
161 }
162
163 pub fn with_ident(self, ident: RustIdent) -> RustIdentWithPath {
164 RustIdentWithPath { path: self, ident }
165 }
166
167 pub fn first(&self) -> Option<RustIdent> {
168 assert!(!self.absolute);
169 self.path.first()
170 }
171
172 pub fn remove_first(&mut self) -> Option<RustIdent> {
173 assert!(!self.absolute);
174 self.path.remove_first()
175 }
176
177 pub fn to_reverse(&self) -> RustPath {
178 assert!(!self.absolute);
179 RustPath {
180 absolute: false,
181 path: self.path.to_reverse(),
182 }
183 }
184
185 pub fn prepend_ident(&mut self, ident: RustIdent) {
186 assert!(!self.absolute);
187 self.path.prepend_ident(ident);
188 }
189
190 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
201 pub fn append_ident(mut self, ident: RustIdent) -> RustPath {
202 self.path.path.push(ident);
203 self
204 }
205
206 pub fn append_with_ident(self, path: RustIdentWithPath) -> RustIdentWithPath {
207 self.append(path.path).with_ident(path.ident)
208 }
209}
210
211impl From<&'_ str> for RustPath {
212 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
225impl From<String> for RustPath {
226 fn from(s: String) -> Self {
227 RustPath::from(&s[..])
228 }
229}
230
231impl fmt::Display for RustPath {
232 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)]
241pub(crate) struct RustIdentWithPath {
242 pub path: RustPath,
243 pub ident: RustIdent,
244}
245
246#[allow(dead_code)]
247impl RustIdentWithPath {
248 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
254 pub fn prepend_ident(&mut self, ident: RustIdent) {
255 self.path.prepend_ident(ident)
256 }
257
258 pub fn to_path(&self) -> RustPath {
259 self.path.clone().append_ident(self.ident.clone())
260 }
261}
262
263impl<S: Into<String>> From<S> for RustIdentWithPath {
264 fn from(s: S) -> Self {
265 RustIdentWithPath::new(s.into())
266 }
267}
268
269impl fmt::Display for RustIdentWithPath {
270 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
271 fmt::Display::fmt(&self.to_path(), f)
272 }
273}