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}