use std::fmt;
use crate::{ident::Ident, span::Span};
use super::ty::Type;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Path {
pub segments: Vec<PathSegment>,
pub span: Span,
}
impl Path {
pub fn from_ident(ident: Ident) -> Self {
let span = ident.span();
Path {
segments: vec![PathSegment { ident, args: None }],
span,
}
}
pub fn is_ident(&self) -> bool {
self.segments.len() == 1 && self.segments[0].args.is_none()
}
pub fn last_ident(&self) -> &Ident {
&self.segments.last().unwrap().ident
}
pub fn last_segment(&self) -> &PathSegment {
self.segments.last().unwrap()
}
}
impl fmt::Display for Path {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for (i, seg) in self.segments.iter().enumerate() {
if i > 0 {
write!(f, ".")?;
}
write!(f, "{}", seg.ident)?;
if let Some(args) = &seg.args {
write!(f, "<")?;
for (j, arg) in args.args.iter().enumerate() {
if j > 0 {
write!(f, ", ")?;
}
match arg {
TypeArgument::Type(ty) => write!(f, "{:?}", ty)?,
TypeArgument::Wildcard(w) => write!(f, "{:?}", w)?,
}
}
write!(f, ">")?;
}
}
Ok(())
}
}
impl fmt::Display for PathSegment {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.ident)?;
if let Some(args) = &self.args {
write!(f, "<")?;
for (j, arg) in args.args.iter().enumerate() {
if j > 0 {
write!(f, ", ")?;
}
match arg {
TypeArgument::Type(ty) => write!(f, "{:?}", ty)?,
TypeArgument::Wildcard(w) => write!(f, "{:?}", w)?,
}
}
write!(f, ">")?;
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct PathSegment {
pub ident: Ident,
pub args: Option<TypeArguments>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct TypeArguments {
pub args: Vec<TypeArgument>,
pub lt_token: Span,
pub gt_tokens: Vec<Span>, }
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum TypeArgument {
Type(Box<Type>),
Wildcard(Wildcard),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Wildcard {
pub bound: Option<WildcardBound>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum WildcardBound {
Extends(Box<Type>),
Super(Box<Type>),
}