#[cfg(feature = "debugger")]
use std::fmt;
use log::{debug, trace};
use serde_derive::{Deserialize, Serialize};
use serde_json::Value;
use crate::errors::*;
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum InputInitializer {
Always(Value),
Once(Value),
}
#[derive(Deserialize, Serialize, Clone)]
pub struct Input {
#[serde(default = "default_initial_value", skip_serializing_if = "Option::is_none")]
pub initializer: Option<InputInitializer>,
#[serde(skip)]
received: Vec<Value>,
}
#[cfg(feature = "debugger")]
impl fmt::Display for Input {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for input_value in &self.received {
write!(f, "{}, ", input_value)?;
}
write!(f, "")
}
}
fn default_initial_value() -> Option<InputInitializer> {
None
}
impl Input {
pub fn new(initial_value: &Option<InputInitializer>) -> Self {
Input {
initializer: initial_value.clone(),
received: Vec::new(),
}
}
#[cfg(feature = "debugger")]
pub fn reset(&mut self) {
self.received.clear();
}
pub fn take(&mut self) -> Result<Value> {
if self.received.is_empty() {
bail!("Trying to take from an empty Input");
}
Ok(self.received.remove(0))
}
pub fn init(&mut self, first_time: bool, io_number: usize) -> bool {
if self.count() > 1 {
return false;
}
let init_value = match (first_time, &self.initializer) {
(true, Some(InputInitializer::Once(one_time))) => Some(one_time.clone()),
(_, Some(InputInitializer::Always(constant))) => Some(constant.clone()),
(_, None) | (false, Some(InputInitializer::Once(_))) => None
};
match init_value {
Some(value) => {
debug!("\t\tInput #{} initialized with '{:?}'", io_number, value);
self.push(value);
true
}
_ => false
}
}
pub fn push(&mut self, value: Value) {
self.received.push(value);
}
pub fn push_array<'a, I>(&mut self, iter: I) where I: Iterator<Item=&'a Value> {
for value in iter {
trace!("\t\t\tPushing array element '{}'", value);
self.received.push(value.clone());
}
}
pub fn count(&self) -> usize { self.received.len() }
}
#[cfg(test)]
mod test {
use serde_json::json;
use serde_json::Value;
use super::Input;
#[test]
fn default_initial_value_is_none() {
assert!(super::default_initial_value().is_none());
}
#[test]
fn no_inputs_initially() {
let input = Input::new(&None);
assert_eq!(input.count(), 0);
}
#[test]
fn accepts_value() {
let mut input = Input::new(&None);
input.push(Value::Null);
assert_ne!(input.count(), 0);
}
#[test]
fn accepts_array() {
let mut input = Input::new(&None);
input.push_array(vec!(json!(5), json!(10), json!(15)).iter());
assert_ne!(input.count(), 0);
}
#[test]
fn gets_full() {
let mut input = Input::new(&None);
input.push(Value::Null);
assert!(input.count() > 0);
}
#[test]
fn take_empties() {
let mut input = Input::new(&None);
input.push(json!(10));
assert_ne!(input.count(), 0);
let _value = input.take().unwrap();
assert_eq!(input.count(), 0);
}
#[cfg(feature = "debugger")]
#[test]
fn reset_empties() {
let mut input = Input::new(&None);
input.push(json!(10));
assert_ne!(input.count(), 0);
input.reset();
assert_eq!(input.count(), 0);
}
}