rust_codegen/
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    /// The name of the type.
9    name: String,
10    /// The type's generics.
11    generics: Vec<Type>,
12}
13
14impl Type {
15    /// Return a new type with the given name.
16    /// 
17    /// # Arguments
18    /// 
19    /// * `name` - The name of the type.
20    /// 
21    /// # Examples
22    /// 
23    /// ```
24    /// use rust_codegen::Type;
25    /// 
26    /// let foo_type = Type::new("Foo");
27    /// ```
28    pub fn new(name: &str) -> Self {
29        Type {
30            name: name.to_string(),
31            generics: vec![],
32        }
33    }
34
35    /// Add a generic to the type.
36    /// 
37    /// # Arguments
38    /// 
39    /// * `ty` - The generic to add to the type.
40    /// 
41    /// # Examples
42    /// 
43    /// ```
44    /// use rust_codegen::Type;
45    /// 
46    /// let mut foo_type = Type::new("Foo");
47    /// foo_type.generic("T");
48    /// ```
49    pub fn generic<T>(&mut self, ty: T) -> &mut Self
50    where
51        T: Into<Type>,
52    {
53        // Make sure that the name doesn't already include generics
54        assert!(
55            !self.name.contains("<"),
56            "type name already includes generics"
57        );
58
59        self.generics.push(ty.into());
60        self
61    }
62
63    /// Formats the struct using the given formatter.
64    /// 
65    /// # Examples
66    /// 
67    /// ```
68    /// use rust_codegen::{Formatter,Type};
69    /// 
70    /// let mut dest = String::new();
71    /// let mut fmt = Formatter::new(&mut dest);
72    /// 
73    /// let mut foo_type = Type::new("Foo");
74    /// foo_type.fmt(&mut fmt);
75    pub fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
76        write!(fmt, "{}", self.name)?;
77        Type::fmt_slice(&self.generics, fmt)
78    }
79
80    /// Formats the type using the given formatter with the given generics.
81    /// 
82    /// # Arguments
83    /// 
84    /// * `generics` - The generics to use.
85    /// * `fmt` - The formatter to use.
86    fn fmt_slice(generics: &[Type], fmt: &mut Formatter<'_>) -> fmt::Result {
87        if !generics.is_empty() {
88            write!(fmt, "<")?;
89
90            for (i, ty) in generics.iter().enumerate() {
91                if i != 0 {
92                    write!(fmt, ", ")?
93                }
94                ty.fmt(fmt)?;
95            }
96
97            write!(fmt, ">")?;
98        }
99
100        Ok(())
101    }
102}
103
104impl<'a> From<&'a str> for Type {
105    fn from(src: &'a str) -> Self {
106        Type::new(src)
107    }
108}
109
110impl From<String> for Type {
111    fn from(src: String) -> Self {
112        Type {
113            name: src,
114            generics: vec![],
115        }
116    }
117}
118
119impl<'a> From<&'a String> for Type {
120    fn from(src: &'a String) -> Self {
121        Type::new(src)
122    }
123}
124
125impl<'a> From<&'a Type> for Type {
126    fn from(src: &'a Type) -> Self {
127        src.clone()
128    }
129}