1use std::fmt;
4
5use crate::{ident::Ident, span::Span};
6
7use super::ty::Type;
8
9#[derive(Debug, Clone, PartialEq, Eq, Hash)]
11pub struct Path {
12 pub segments: Vec<PathSegment>,
13 pub span: Span,
14}
15
16impl Path {
17 pub fn from_ident(ident: Ident) -> Self {
19 let span = ident.span();
20 Path {
21 segments: vec![PathSegment { ident, args: None }],
22 span,
23 }
24 }
25
26 pub fn is_ident(&self) -> bool {
28 self.segments.len() == 1 && self.segments[0].args.is_none()
29 }
30
31 pub fn last_ident(&self) -> &Ident {
33 &self.segments.last().unwrap().ident
34 }
35
36 pub fn last_segment(&self) -> &PathSegment {
38 self.segments.last().unwrap()
39 }
40}
41
42impl fmt::Display for Path {
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44 for (i, seg) in self.segments.iter().enumerate() {
45 if i > 0 {
46 write!(f, ".")?;
47 }
48 write!(f, "{}", seg.ident)?;
49 if let Some(args) = &seg.args {
50 write!(f, "<")?;
51 for (j, arg) in args.args.iter().enumerate() {
52 if j > 0 {
53 write!(f, ", ")?;
54 }
55 match arg {
56 TypeArgument::Type(ty) => write!(f, "{:?}", ty)?,
57 TypeArgument::Wildcard(w) => write!(f, "{:?}", w)?,
58 }
59 }
60 write!(f, ">")?;
61 }
62 }
63 Ok(())
64 }
65}
66
67impl fmt::Display for PathSegment {
68 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 write!(f, "{}", self.ident)?;
70 if let Some(args) = &self.args {
71 write!(f, "<")?;
72 for (j, arg) in args.args.iter().enumerate() {
73 if j > 0 {
74 write!(f, ", ")?;
75 }
76 match arg {
77 TypeArgument::Type(ty) => write!(f, "{:?}", ty)?,
78 TypeArgument::Wildcard(w) => write!(f, "{:?}", w)?,
79 }
80 }
81 write!(f, ">")?;
82 }
83 Ok(())
84 }
85}
86
87#[derive(Debug, Clone, PartialEq, Eq, Hash)]
89pub struct PathSegment {
90 pub ident: Ident,
91 pub args: Option<TypeArguments>,
92}
93
94#[derive(Debug, Clone, PartialEq, Eq, Hash)]
96pub struct TypeArguments {
97 pub args: Vec<TypeArgument>,
98 pub lt_token: Span,
99 pub gt_tokens: Vec<Span>, }
101
102#[derive(Debug, Clone, PartialEq, Eq, Hash)]
104pub enum TypeArgument {
105 Type(Box<Type>),
107 Wildcard(Wildcard),
109}
110
111#[derive(Debug, Clone, PartialEq, Eq, Hash)]
113pub struct Wildcard {
114 pub bound: Option<WildcardBound>,
115 pub span: Span,
116}
117
118#[derive(Debug, Clone, PartialEq, Eq, Hash)]
120pub enum WildcardBound {
121 Extends(Box<Type>),
122 Super(Box<Type>),
123}