use analysis::{Description, Enum, Function};
use synthesis::{TestClass, TestFunction};
macro_rules! implement_conversion {
($t:ident) => {
impl EntityConversion for $t {
fn convert(entity_type: &mut EntityType) -> Option<&mut $t> {
match entity_type {
EntityType::$t(entity) => Some(entity),
_ => None,
}
}
}
};
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum EntityType {
Entity(Entity),
Enum(Enum),
Function(Function),
TestClass(TestClass),
TestFunction(TestFunction),
}
pub trait EntityConversion {
fn convert(entity_type: &mut EntityType) -> Option<&mut Self>;
}
implement_conversion!(Entity);
implement_conversion!(Enum);
implement_conversion!(Function);
implement_conversion!(TestClass);
implement_conversion!(TestFunction);
fn convert<T>(entity_type: &mut EntityType) -> Option<&mut T>
where
T: EntityConversion,
{
T::convert(entity_type)
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Entity {
pub name: String,
pub entities: Vec<EntityType>,
pub description: Option<Description>,
}
impl Entity {
pub fn new<S: Into<String>>(name: S) -> Self {
Self {
name: name.into(),
entities: Vec::new(),
description: None,
}
}
pub fn add_entity<T>(&mut self, entity: EntityType) -> Option<&mut T>
where
T: EntityConversion,
{
self.entities.push(entity);
if let Some(entity) = self.entities.last_mut() {
return convert(entity);
}
None
}
pub fn functions(&self) -> Vec<&Function> {
let mut entity_vec: Vec<&Function> = Vec::new();
for entity in &self.entities {
if let EntityType::Function(fct) = entity {
entity_vec.push(&fct);
}
}
return entity_vec;
}
pub fn set_description(&mut self, description: &str) {
if self.description.is_none() {
self.description = Some(Description::new());
}
if let Some(desc) = &mut self.description {
desc.set(description);
}
}
}