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
use super::model_trait::AsModel; use serde::de; use serde::Deserializer; use std::collections::HashMap; use lazy_static::lazy_static; use std::sync::Mutex; pub type ModelConstructor = fn(serde_yaml::Value) -> Option<Box<dyn AsModel>>; lazy_static! { static ref CONSTRUCTORS: Mutex<HashMap<&'static str, ModelConstructor>> = { let mut m = HashMap::new(); m.insert("Batcher", super::Batcher::from_value as ModelConstructor); m.insert( "ExclusiveGateway", super::ExclusiveGateway::from_value as ModelConstructor, ); m.insert("Gate", super::Gate::from_value as ModelConstructor); m.insert( "Generator", super::Generator::from_value as ModelConstructor, ); m.insert( "LoadBalancer", super::LoadBalancer::from_value as ModelConstructor, ); m.insert( "ParallelGateway", super::ParallelGateway::from_value as ModelConstructor, ); m.insert( "Processor", super::Processor::from_value as ModelConstructor, ); m.insert( "StochasticGate", super::StochasticGate::from_value as ModelConstructor, ); m.insert( "Stopwatch", super::Stopwatch::from_value as ModelConstructor, ); m.insert("Storage", super::Storage::from_value as ModelConstructor); Mutex::new(m) }; static ref VARIANTS: Vec<&'static str> = { CONSTRUCTORS .lock() .unwrap() .iter() .map(|(k, _)| k) .copied() .collect::<Vec<_>>() }; } pub fn register(model_type: &'static str, model_constructor: ModelConstructor) { CONSTRUCTORS .lock() .unwrap() .insert(model_type, model_constructor); } pub fn create<'de, D: Deserializer<'de>>( model_type: &str, extra_fields: serde_yaml::Value, ) -> Result<Box<dyn AsModel>, D::Error> { let model = match CONSTRUCTORS.lock().unwrap().get(model_type) { Some(constructor) => constructor(extra_fields), None => None, }; match model { Some(model) => Ok(model), None => Err(de::Error::unknown_variant(model_type, &VARIANTS)), } }