thinlinelib/
entity.rs

1use analysis::{Description, Enum, Function};
2use synthesis::{TestClass, TestFunction};
3
4////////////////////////////////////////////////////////////////////////////////
5
6macro_rules! implement_conversion {
7    ($t:ident) => {
8        impl EntityConversion for $t {
9            fn convert(entity_type: &mut EntityType) -> Option<&mut $t> {
10                match entity_type {
11                    EntityType::$t(entity) => Some(entity),
12                    _ => None,
13                }
14            }
15        }
16    };
17}
18
19/// The different types an Entitiy can have.
20#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
21pub enum EntityType {
22    /// The index of a new entity hierarchy.
23    Entity(Entity),
24
25    /// An enumeration.
26    Enum(Enum),
27
28    /// A function.
29    Function(Function),
30
31    /// A test class.
32    TestClass(TestClass),
33
34    /// A test function.
35    TestFunction(TestFunction),
36}
37
38pub trait EntityConversion {
39    fn convert(entity_type: &mut EntityType) -> Option<&mut Self>;
40}
41
42implement_conversion!(Entity);
43implement_conversion!(Enum);
44implement_conversion!(Function);
45implement_conversion!(TestClass);
46implement_conversion!(TestFunction);
47
48fn convert<T>(entity_type: &mut EntityType) -> Option<&mut T>
49where
50    T: EntityConversion,
51{
52    T::convert(entity_type)
53}
54
55////////////////////////////////////////////////////////////////////////////////
56
57/// The representation of an Entity as a possbile generic node on the
58/// abstract syntax tree. An Entity has to be kind of a EntityType.
59#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
60pub struct Entity {
61    pub name: String,
62    pub entities: Vec<EntityType>,
63    pub description: Option<Description>,
64}
65
66impl Entity {
67    /// Creates a new Entity instance.
68    ///
69    /// # Example
70    ///
71    /// ```
72    /// use thinlinelib::entity::Entity;
73    ///
74    /// let class = Entity::new("testClass");
75    ///
76    /// assert_eq!(class.name, "testClass");
77    /// assert!(class.entities.is_empty());
78    /// ```
79    pub fn new<S: Into<String>>(name: S) -> Self {
80        Self {
81            name: name.into(),
82            entities: Vec::new(),
83            description: None,
84        }
85    }
86
87    /// Adds an Entity to the Entity instance.
88    ///
89    /// # Example
90    ///
91    /// ```
92    /// use thinlinelib::entity::{Entity, EntityType};
93    ///
94    /// let mut entity = Entity::new("outer_entity");
95    /// let entity_type = EntityType::Entity(Entity::new("inner_entity"));
96    /// entity.add_entity::<Entity>(entity_type);
97    ///
98    /// assert_eq!(entity.entities.len(), 1);
99    /// ```
100    pub fn add_entity<T>(&mut self, entity: EntityType) -> Option<&mut T>
101    where
102        T: EntityConversion,
103    {
104        self.entities.push(entity);
105        if let Some(entity) = self.entities.last_mut() {
106            return convert(entity);
107        }
108
109        None
110    }
111
112    /// Returns the functions of an entity.
113    pub fn functions(&self) -> Vec<&Function> {
114        let mut entity_vec: Vec<&Function> = Vec::new();
115        for entity in &self.entities {
116            if let EntityType::Function(fct) = entity {
117                entity_vec.push(&fct);
118            }
119        }
120        return entity_vec;
121    }
122
123    /// Sets the description for the Entity.
124    pub fn set_description(&mut self, description: &str) {
125        if self.description.is_none() {
126            self.description = Some(Description::new());
127        }
128
129        if let Some(desc) = &mut self.description {
130            desc.set(description);
131        }
132    }
133}