1use std::fmt::{self, Write};
2
3use crate::formatter::Formatter;
4
5#[derive(Debug, Clone)]
7pub struct Type {
8 name: String,
9 generics: Vec<Type>,
10}
11
12impl Type {
13 pub fn new(name: &str) -> Self {
15 Self {
16 name: name.to_string(),
17 generics: vec![],
18 }
19 }
20
21 pub fn generic<T>(&mut self, ty: T) -> &mut Self
23 where
24 T: Into<Self>,
25 {
26 assert!(
28 !self.name.contains('<'),
29 "type name already includes generics"
30 );
31
32 self.generics.push(ty.into());
33 self
34 }
35
36 pub fn path(&self, path: &str) -> Self {
40 assert!(!self.name.contains("::"));
42
43 let mut name = path.to_string();
44 name.push_str("::");
45 name.push_str(&self.name);
46
47 Self {
48 name,
49 generics: self.generics.clone(),
50 }
51 }
52
53 pub fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
55 write!(fmt, "{}", self.name)?;
56 Self::fmt_slice(&self.generics, fmt)
57 }
58
59 fn fmt_slice(generics: &[Self], fmt: &mut Formatter<'_>) -> fmt::Result {
60 if !generics.is_empty() {
61 write!(fmt, "<")?;
62
63 for (i, ty) in generics.iter().enumerate() {
64 if i != 0 {
65 write!(fmt, ", ")?
66 }
67 ty.fmt(fmt)?;
68 }
69
70 write!(fmt, ">")?;
71 }
72
73 Ok(())
74 }
75}
76
77impl From<&str> for Type {
78 fn from(src: &str) -> Self {
79 Self::new(src)
80 }
81}
82
83impl From<String> for Type {
84 fn from(src: String) -> Self {
85 Self {
86 name: src,
87 generics: vec![],
88 }
89 }
90}
91
92impl From<&String> for Type {
93 fn from(src: &String) -> Self {
94 Self::new(src)
95 }
96}
97
98impl From<&Type> for Type {
99 fn from(src: &Self) -> Self {
100 src.clone()
101 }
102}