diff options
Diffstat (limited to '2.27.1/src/rust_name.rs')
-rw-r--r-- | 2.27.1/src/rust_name.rs | 273 |
1 files changed, 273 insertions, 0 deletions
diff --git a/2.27.1/src/rust_name.rs b/2.27.1/src/rust_name.rs new file mode 100644 index 0000000..234925b --- /dev/null +++ b/2.27.1/src/rust_name.rs @@ -0,0 +1,273 @@ +use std::fmt; +use std::iter; + +/// Valid Rust identifier +#[derive(Eq, PartialEq, Debug, Clone)] +pub(crate) struct RustIdent(String); + +#[allow(dead_code)] +impl RustIdent { + pub fn new(s: &str) -> RustIdent { + assert!(!s.is_empty()); + assert!(!s.contains("/"), "{}", s); + assert!(!s.contains("."), "{}", s); + assert!(!s.contains(":"), "{}", s); + RustIdent(s.to_owned()) + } + + pub fn super_ident() -> RustIdent { + RustIdent::new("super") + } + + pub fn get(&self) -> &str { + &self.0 + } + + pub fn into_string(self) -> String { + self.0 + } + + pub fn to_path(&self) -> RustIdentWithPath { + RustIdentWithPath::from(&self.0) + } +} + +impl fmt::Display for RustIdent { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&self.get(), f) + } +} + +impl From<&'_ str> for RustIdent { + fn from(s: &str) -> Self { + RustIdent::new(s) + } +} + +impl From<String> for RustIdent { + fn from(s: String) -> Self { + RustIdent::new(&s) + } +} + +impl Into<String> for RustIdent { + fn into(self) -> String { + self.0 + } +} + +#[derive(Default, Eq, PartialEq, Debug, Clone)] +pub(crate) struct RustRelativePath { + path: Vec<RustIdent>, +} + +#[allow(dead_code)] +impl RustRelativePath { + pub fn into_path(self) -> RustPath { + RustPath { + absolute: false, + path: self, + } + } + + pub fn empty() -> RustRelativePath { + RustRelativePath { path: Vec::new() } + } + + pub fn from_components<I: IntoIterator<Item = RustIdent>>(i: I) -> RustRelativePath { + RustRelativePath { + path: i.into_iter().collect(), + } + } + + pub fn is_empty(&self) -> bool { + self.path.is_empty() + } + + pub fn first(&self) -> Option<RustIdent> { + self.path.iter().cloned().next() + } + + pub fn remove_first(&mut self) -> Option<RustIdent> { + if self.path.is_empty() { + None + } else { + Some(self.path.remove(0)) + } + } + + pub fn prepend_ident(&mut self, ident: RustIdent) { + self.path.insert(0, ident); + } + + pub fn append(mut self, path: RustRelativePath) -> RustRelativePath { + for c in path.path { + self.path.push(c); + } + self + } + + pub fn push_ident(&mut self, ident: RustIdent) { + self.path.push(ident); + } + + pub fn _append_ident(mut self, ident: RustIdent) -> RustRelativePath { + self.push_ident(ident); + self + } + + pub fn to_reverse(&self) -> RustRelativePath { + RustRelativePath::from_components( + iter::repeat(RustIdent::super_ident()).take(self.path.len()), + ) + } +} + +#[derive(Default, Eq, PartialEq, Debug, Clone)] +pub(crate) struct RustPath { + absolute: bool, + path: RustRelativePath, +} + +impl fmt::Display for RustRelativePath { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for (i, c) in self.path.iter().enumerate() { + if i != 0 { + write!(f, "::")?; + } + write!(f, "{}", c)?; + } + Ok(()) + } +} + +impl From<&'_ str> for RustRelativePath { + fn from(s: &str) -> Self { + RustRelativePath { + path: s.split("::").map(RustIdent::from).collect(), + } + } +} + +#[allow(dead_code)] +impl RustPath { + pub fn is_absolute(&self) -> bool { + self.absolute + } + + pub fn is_empty(&self) -> bool { + assert!(!self.absolute); + self.path.is_empty() + } + + pub fn with_ident(self, ident: RustIdent) -> RustIdentWithPath { + RustIdentWithPath { path: self, ident } + } + + pub fn first(&self) -> Option<RustIdent> { + assert!(!self.absolute); + self.path.first() + } + + pub fn remove_first(&mut self) -> Option<RustIdent> { + assert!(!self.absolute); + self.path.remove_first() + } + + pub fn to_reverse(&self) -> RustPath { + assert!(!self.absolute); + RustPath { + absolute: false, + path: self.path.to_reverse(), + } + } + + pub fn prepend_ident(&mut self, ident: RustIdent) { + assert!(!self.absolute); + self.path.prepend_ident(ident); + } + + pub fn append(self, path: RustPath) -> RustPath { + if path.absolute { + path + } else { + RustPath { + absolute: self.absolute, + path: self.path.append(path.path), + } + } + } + + pub fn append_ident(mut self, ident: RustIdent) -> RustPath { + self.path.path.push(ident); + self + } + + pub fn append_with_ident(self, path: RustIdentWithPath) -> RustIdentWithPath { + self.append(path.path).with_ident(path.ident) + } +} + +impl From<&'_ str> for RustPath { + fn from(s: &str) -> Self { + let (s, absolute) = if s.starts_with("::") { + (&s[2..], true) + } else { + (s, false) + }; + RustPath { + absolute, + path: RustRelativePath::from(s), + } + } +} + +impl From<String> for RustPath { + fn from(s: String) -> Self { + RustPath::from(&s[..]) + } +} + +impl fmt::Display for RustPath { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if self.absolute { + write!(f, "::")?; + } + write!(f, "{}", self.path) + } +} + +#[derive(Eq, PartialEq, Debug, Clone)] +pub(crate) struct RustIdentWithPath { + pub path: RustPath, + pub ident: RustIdent, +} + +#[allow(dead_code)] +impl RustIdentWithPath { + pub fn new(s: String) -> RustIdentWithPath { + let mut path = RustPath::from(s); + let ident = path.path.path.pop().unwrap(); + RustIdentWithPath { path, ident } + } + + pub fn prepend_ident(&mut self, ident: RustIdent) { + self.path.prepend_ident(ident) + } + + pub fn to_path(&self) -> RustPath { + self.path.clone().append_ident(self.ident.clone()) + } +} + +impl<S: Into<String>> From<S> for RustIdentWithPath { + fn from(s: S) -> Self { + RustIdentWithPath::new(s.into()) + } +} + +impl fmt::Display for RustIdentWithPath { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&self.to_path(), f) + } +} |