use std::sync::Arc; use crate::runtime::error as old_error; use crate::Polarity; use crate::protocol::*; use crate::protocol::eval::*; use super::registry::Registry; enum AddComponentError { ModuleDoesNotExist, ConnectorDoesNotExist, InvalidArgumentType(usize), // value is index of (first) invalid argument } struct Runtime { protocol: Arc, } impl Runtime { pub fn new(pd: Arc) -> Self { Self{ protocol: pd } } pub fn add_component(&mut self, module: &str, procedure: &str, values: ValueGroup) -> Result<(), AddComponentError> { use AddComponentError as ACE; use old_error::AddComponentError as OldACE; // TODO: Allow the ValueGroup to contain any kind of value // TODO: Remove the responsibility of adding a component from the PD // Lookup module and the component // TODO: Remove this error enum translation let port_polarities = match self.protocol.component_polarities(module.as_bytes(), procedure.as_bytes()) { Ok(polarities) => polarities, Err(reason) => match reason { OldACE::NonPortTypeParameters => return Err(ACE::InvalidArgumentType(0)), OldACE::NoSuchModule => return Err(ACE::ModuleDoesNotExist), OldACE::NoSuchComponent => return Err(ACE::ModuleDoesNotExist), _ => unreachable!(), } }; // Make sure supplied values (and types) are correct let mut ports = Vec::with_capacity(values.values.len()); for (value_idx, value) in values.values.iter().enumerate() { let polarity = &port_polarities[value_idx]; match value { Value::Input(port_id) => { if *polarity != Polarity::Getter { return Err(ACE::InvalidArgumentType(value_idx)) } ports.push(*port_id); }, Value::Output(port_id) => { if *polarity != Polarity::Putter { return Err(ACE::InvalidArgumentType(value_idx)) } ports.push(*port_id); }, _ => return Err(ACE::InvalidArgumentType(value_idx)) } } // Instantiate the component let component_state = self.protocol.new_component(module.as_bytes(), procedure.as_bytes(), &ports); } }