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