Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #![feature(box_syntax, box_patterns)]
- extern crate futures;
- use std::collections::BTreeMap;
- use std::rc::Rc;
- use std::marker::PhantomData;
- use futures::future::{err, ok};
- use futures::Future;
- #[derive(Clone, Debug, PartialEq, Eq)]
- pub enum ValueType {
- Character,
- Integer,
- Decimal,
- BitField(usize /* length */),
- List(Rc<ValueType>, Option<usize> /* max length */),
- Collection(Rc<[ValueType]>),
- }
- #[derive(Clone, Debug)]
- pub enum Value {
- Character(char),
- Integer(i32),
- Decimal(f32),
- BitField(usize, Rc<[bool]>),
- List(Rc<ValueType>, Option<usize>, Rc<[Value]>),
- Collection(Rc<[ValueType]>, Rc<[Value]>),
- }
- impl From<Value> for ValueType {
- fn from(value: Value) -> Self {
- match value {
- Value::Character(_) => ValueType::Character,
- Value::Integer(_) => ValueType::Integer,
- Value::Decimal(_) => ValueType::Decimal,
- Value::BitField(len, _) => ValueType::BitField(len),
- Value::List(value_type, max_length, _) => ValueType::List(value_type, max_length),
- Value::Collection(value_types, _) => ValueType::Collection(value_types),
- _ => unimplemented!(),
- }
- }
- }
- impl Value {
- pub fn get_type(&self) -> ValueType {
- match self {
- Value::Character(_) => ValueType::Character,
- Value::Integer(_) => ValueType::Integer,
- Value::Decimal(_) => ValueType::Decimal,
- Value::BitField(len, _) => ValueType::BitField(*len),
- Value::List(value_type, max_length, _) => {
- ValueType::List(value_type.clone(), *max_length)
- }
- Value::Collection(value_types, _) => ValueType::Collection(value_types.clone()),
- _ => unimplemented!(),
- }
- }
- }
- impl ValueType {
- pub fn validate(&self, val: &Value) -> bool {
- *self == val.get_type()
- }
- pub fn default(&self) -> Value {
- match self {
- ValueType::Character => Value::Character('\x00'),
- ValueType::Integer => Value::Integer(0),
- ValueType::Decimal => Value::Decimal(0.0f32),
- ValueType::BitField(len) => {
- Value::BitField(*len, Rc::from(Vec::with_capacity(*len).as_slice()))
- }
- ValueType::List(value_type, len) => match *len {
- Some(len) => {
- let mut list = Vec::with_capacity(len);
- for i in 0..len {
- list.push((**value_type).default());
- }
- Value::List(value_type.clone(), Some(len), Rc::from(list.as_slice()))
- }
- None => Value::List(value_type.clone(), None, Rc::from(vec![].as_slice())),
- },
- ValueType::Collection(types) => {
- let mut collection = Vec::new();
- for t in types.as_ref() {
- collection.push(t.default());
- }
- Value::Collection(Rc::from(types.as_ref()), Rc::from(collection.as_slice()))
- }
- }
- }
- }
- pub struct ValueDescriptor {
- value_type: ValueType,
- default: Option<Value>,
- }
- impl ValueDescriptor {
- pub fn new(value_type: ValueType, default: Option<Value>) -> Result<ValueDescriptor, String> {
- match default {
- Some(val) => {
- if !value_type.validate(&val) {
- return Err(format!(
- "Incompatible types: '{:?}' and '{:?}'",
- value_type,
- val.get_type()
- ));
- }
- return Ok(ValueDescriptor {
- value_type,
- default: Some(val),
- });
- }
- None => Ok(ValueDescriptor {
- value_type,
- default: None,
- }),
- }
- }
- pub fn default(&self) -> Value {
- match &self.default {
- Some(val) => val.clone(),
- None => self.value_type.default(),
- }
- }
- }
- type ValueConstraint = dyn Fn(Value, Value) -> bool;
- pub struct DeviceType<'a> {
- parameters: BTreeMap<&'a str, ValueDescriptor>,
- constants: BTreeMap<&'a str, ValueDescriptor>,
- results: BTreeMap<&'a str, ValueDescriptor>,
- }
- pub struct Input<'a> {
- value_type: ValueType,
- value: &'a dyn Future<Output = Result<Value, ()>>,
- }
- pub struct Output<'a> {
- value_type: ValueType,
- value: Box<dyn Future<Output = Result<Value, ()>>>,
- phantom: PhantomData<&'a Value>
- }
- pub struct Constant {
- value_type: ValueType,
- value: Box<dyn Future<Output = Result<Value, ()>>>,
- }
- impl<'a> Output<'a> {
- pub fn attach(&self, input: &mut Input<'a>) {
- input.value = self.value.as_ref();
- }
- }
- impl Constant {
- pub fn attach<'a>(&self, input: &mut Input<'a>) -> &Self {
- input.value = self.value.as_ref();
- self
- }
- }
- pub struct Device<'a> {
- inputs: BTreeMap<&'a str, Input<'a>>,
- constants: BTreeMap<&'a str, Constant>,
- outputs: BTreeMap<&'a str, Output<'a>>,
- }
- impl<'a> Device<'a> {
- pub fn get_outputs(&self) -> Vec<(&str, ValueType)> {
- self.outputs
- .iter()
- .map(|(k, v)| (*k, v.value_type))
- .collect()
- }
- pub fn get_constants(&self) -> Vec<(&str, ValueType, Value)> {
- self.constants
- .iter()
- .map(|(k, v)| (*k, v.value_type, v.value))
- .collect()
- }
- }
- fn main() {
- println!("Hello, world!");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement