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