codegen_rs/
type.rs

1use std::fmt::{self, Write};
2
3use crate::formatter::Formatter;
4
5/// Defines a type.
6#[derive(Debug, Clone)]
7pub struct Type {
8    name: String,
9    generics: Vec<Type>,
10}
11
12impl Type {
13    /// Return a new type with the given name.
14    pub fn new(name: &str) -> Self {
15        Self {
16            name: name.to_string(),
17            generics: vec![],
18        }
19    }
20
21    /// Add a generic to the type.
22    pub fn generic<T>(&mut self, ty: T) -> &mut Self
23    where
24        T: Into<Self>,
25    {
26        // Make sure that the name doesn't already include generics
27        assert!(
28            !self.name.contains('<'),
29            "type name already includes generics"
30        );
31
32        self.generics.push(ty.into());
33        self
34    }
35
36    /// Rewrite the `Type` with the provided path
37    ///
38    /// TODO: Is this needed?
39    pub fn path(&self, path: &str) -> Self {
40        // TODO: This isn't really correct
41        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    /// Formats the struct using the given formatter.
54    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}