blob: 234925b44e03bad7f1502e6f4aebe5098d201708 [file] [log] [blame]
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)
}
}