rstgen/csharp/
field.rs

1//! Data structure for fields
2
3use con_::Con;
4use csharp::{BlockComment, Modifier};
5use {Cons, Csharp, Element, IntoTokens, Tokens};
6
7/// Model for Csharp Fields.
8#[derive(Debug, Clone)]
9pub struct Field<'el> {
10    /// Attributes of field.
11    pub attributes: Tokens<'el, Csharp<'el>>,
12    /// Modifiers of field.
13    pub modifiers: Vec<Modifier>,
14    /// Comments associated with this field.
15    pub comments: Vec<Cons<'el>>,
16    /// Block of field.
17    pub block: Option<Tokens<'el, Csharp<'el>>>,
18    /// Type of field.
19    ty: Csharp<'el>,
20    /// Name of field.
21    name: Cons<'el>,
22}
23
24impl<'el> Field<'el> {
25    /// Create a new field.
26    pub fn new<T, N>(ty: T, name: N) -> Field<'el>
27    where
28        T: Into<Csharp<'el>>,
29        N: Into<Cons<'el>>,
30    {
31        use self::Modifier::*;
32
33        Field {
34            attributes: Tokens::new(),
35            modifiers: vec![Private],
36            comments: vec![],
37            block: None,
38            ty: ty.into(),
39            name: name.into(),
40        }
41    }
42
43    /// Push an attribute.
44    pub fn attribute<T>(&mut self, attribute: T)
45    where
46        T: IntoTokens<'el, Csharp<'el>>,
47    {
48        self.attributes.push(attribute.into_tokens());
49    }
50
51    /// Set block for field.
52    pub fn block<I>(&mut self, block: I)
53    where
54        I: IntoTokens<'el, Csharp<'el>>,
55    {
56        self.block = Some(block.into_tokens());
57    }
58
59    /// The variable of the field.
60    pub fn var(&self) -> Cons<'el> {
61        self.name.clone()
62    }
63
64    /// The type of the field.
65    pub fn ty(&self) -> Csharp<'el> {
66        self.ty.clone()
67    }
68}
69
70into_tokens_impl_from!(Field<'el>, Csharp<'el>);
71
72impl<'el> IntoTokens<'el, Csharp<'el>> for Field<'el> {
73    fn into_tokens(self) -> Tokens<'el, Csharp<'el>> {
74        let mut tokens = Tokens::new();
75
76        tokens.push_unless_empty(BlockComment(self.comments));
77
78        if !self.attributes.is_empty() {
79            tokens.push(self.attributes);
80            tokens.append(Element::PushSpacing);
81        }
82
83        tokens.append({
84            let mut sig = Tokens::new();
85
86            sig.extend(self.modifiers.into_tokens());
87
88            sig.append(self.ty);
89            sig.append(self.name);
90
91            if let Some(block) = self.block {
92                sig.append({
93                    let mut b = Tokens::new();
94                    b.append("{");
95                    b.nested(block);
96                    b.push("}");
97                    b
98                });
99            }
100
101            sig.join_spacing()
102        });
103
104        tokens
105    }
106}
107
108impl<'el> From<Field<'el>> for Element<'el, Csharp<'el>> {
109    fn from(f: Field<'el>) -> Self {
110        Element::Append(Con::Owned(f.into_tokens()))
111    }
112}
113
114#[cfg(test)]
115mod tests {
116    use csharp::{Field, INT32};
117    use tokens::Tokens;
118
119    fn field() -> Field<'static> {
120        Field::new(INT32, "foo")
121    }
122
123    #[test]
124    fn test_with_comments() {
125        let mut c = field();
126        c.comments.push("Hello World".into());
127        let t: Tokens<_> = c.into();
128        assert_eq!(
129            Ok(String::from("/// Hello World\nprivate Int32 foo")),
130            t.to_string()
131        );
132    }
133
134    #[test]
135    fn test_no_comments() {
136        let t = Tokens::from(field());
137        assert_eq!(Ok(String::from("private Int32 foo")), t.to_string());
138    }
139}