libautomotive 0.1.2

A Rust library for automotive systems and protocols
Documentation
use crate::error::AutomotiveError;
use crate::types::Frame;
use std::sync::{Arc, Mutex};

pub struct MockLinPhysical {
    response_fn: Option<Box<dyn Fn(&Frame) -> Result<Frame, AutomotiveError> + Send>>,
    last_sent: Arc<Mutex<Option<Frame>>>,
}

impl MockLinPhysical {
    pub fn new(response_fn: Option<Box<dyn Fn(&Frame) -> Result<Frame, AutomotiveError> + Send>>) -> Self {
        MockLinPhysical {
            response_fn,
            last_sent: Arc::new(Mutex::new(None)),
        }
    }

    pub fn new_echo() -> Self {
        MockLinPhysical::new(Some(Box::new(|frame: &Frame| {
            Ok(Frame {
                id: frame.id,
                data: frame.data.clone(),
                timestamp: 0,
                is_extended: false,
                is_fd: false,
            })
        })))
    }

    pub fn new_error() -> Self {
        MockLinPhysical::new(Some(Box::new(|_frame: &Frame| {
            Err(AutomotiveError::NotInitialized)
        })))
    }

    pub fn get_last_sent(&self) -> Option<Frame> {
        self.last_sent.lock().unwrap().clone()
    }
}

impl crate::physical::PhysicalLayer for MockLinPhysical {
    fn open(&mut self) -> Result<(), AutomotiveError> {
        Ok(())
    }

    fn close(&mut self) -> Result<(), AutomotiveError> {
        Ok(())
    }

    fn write_frame(&mut self, frame: &Frame) -> Result<(), AutomotiveError> {
        *self.last_sent.lock().unwrap() = Some(frame.clone());
        Ok(())
    }

    fn read_frame(&mut self) -> Result<Frame, AutomotiveError> {
        if let Some(last_frame) = self.last_sent.lock().unwrap().as_ref() {
            if let Some(response_fn) = &self.response_fn {
                response_fn(last_frame)
            } else {
                Err(AutomotiveError::NotInitialized)
            }
        } else {
            Err(AutomotiveError::NotInitialized)
        }
    }
}