rust-servo 0.1.1

A simple servo engine written rust.
Documentation
use std::{fmt::Display, time::Instant};

use num_traits::Num;

use crate::servo::{ControlValue, Servo, ServoInput};

pub struct Engine<T: Servo> {
    pub servo: T,
    pub last_read_timestamp: Option<Instant>,
    pub num_reads: u64,
}

impl<T: Servo + Display> Display for Engine<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "Engine runner [{}] has {} total read(s)",
            self.servo, self.num_reads
        )
    }
}

impl<T: Servo> Engine<T> {
    pub fn new(servo: T) -> Self {
        Self {
            servo,
            last_read_timestamp: None,
            num_reads: 0,
        }
    }

    pub fn reset(&mut self) {
        self.last_read_timestamp = None;
        self.num_reads = 0;
    }

    pub fn next<N: Num>(&mut self, process_value: N) -> ControlValue {
        let servo_input = ServoInput {
            process_value,
            delta_t: None,
        };
        let servo_result = self.servo.read(&servo_input);

        self.num_reads += 1;
        servo_result.unwrap()
    }
}

#[cfg(test)]
mod tests {
    use std::fmt::Display;

    use super::Engine;
    use crate::servo::{ControlValue, Servo};

    struct TestController {}

    impl TestController {
        fn new() -> Self {
            Self {}
        }
    }

    impl Servo for TestController {
        fn read<T: num_traits::Num>(
            &mut self,
            _servo_input: &crate::servo::ServoInput<T>,
        ) -> Result<crate::servo::ControlValue, crate::servo::ReadInputError> {
            Ok(ControlValue { value: 0.0 })
        }
    }

    impl Display for TestController {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            write!(f, "")
        }
    }

    #[test]
    fn should_instantiate_engine_correctly() {
        let servo = TestController::new();
        let engine = Engine::new(servo);
        assert!(engine.last_read_timestamp.is_none());
        assert_eq!(engine.num_reads, 0);
    }

    #[test]
    fn should_invoke_servo_engine_correctly() {
        let servo = TestController::new();
        let mut engine = Engine::new(servo);
        engine.next(1);
        engine.next(2);
        engine.next(3);
        assert_eq!(engine.num_reads, 3);
    }

    #[test]
    fn should_reset_engine_correctly() {
        let servo = TestController::new();
        let mut engine = Engine::new(servo);
        for _ in 0..5 {
            engine.next(0);
        }
        assert_eq!(engine.num_reads, 5);
        engine.reset();
        assert_eq!(engine.num_reads, 0);
    }
}