jabi 0.1.1

Rust library for JABI (Just Another Bridge Interface)
Documentation
use crate::interfaces::InterfaceRequest;
use crate::Error;
use deku::{DekuContainerRead, DekuContainerWrite, DekuRead, DekuUpdate, DekuWrite};

pub enum InstID {
    Metadata = 0,
    CAN = 1,
    I2C = 2,
    GPIO = 3,
    PWM = 4,
    ADC = 5,
    DAC = 6,
    SPI = 7,
    UART = 8,
    LIN = 9,
}

enum Func {
    Serial = 0,
    NumInst = 1,
    Echo = 2,
    ReqMaxSize = 3,
    RespMaxSize = 4,
    Custom = 5,
}

fn gen_req(f: Func, payload: Vec<u8>) -> Result<InterfaceRequest, Error> {
    let mut r = InterfaceRequest {
        periph_id: InstID::Metadata as u16,
        periph_idx: 0,
        periph_fn: f as u16,
        payload_len: 0,
        payload: payload,
    };
    r.update().map_or(Err(Error::PacketFormat), |_| Ok(r))
}

impl crate::Device {
    pub fn serial(&self) -> Result<String, Error> {
        let resp = self.send(&gen_req(Func::Serial, vec![])?)?;
        match String::from_utf8(resp) {
            Ok(s) => Ok(s),
            Err(_) => Err(Error::Unknown),
        }
    }

    pub fn num_inst(&self, id: InstID) -> Result<usize, Error> {
        #[derive(DekuWrite)]
        #[deku(endian = "little")]
        struct NumInstRequest {
            periph_id: u16,
        }
        #[derive(DekuRead)]
        #[deku(endian = "little")]
        struct NumInstResponse {
            num_idx: u16,
        }
        let req = NumInstRequest {
            periph_id: id as u16,
        };
        let resp = self.send(&gen_req(Func::NumInst, req.to_bytes().unwrap())?)?;
        match NumInstResponse::from_bytes((&resp, 0)) {
            Ok(((s, _), ret)) if s.len() == 0 => Ok(ret.num_idx as usize),
            _ => Err(Error::PacketFormat),
        }
    }

    pub fn echo(&self, s: Vec<u8>) -> Result<Vec<u8>, Error> {
        self.send(&gen_req(Func::Echo, s)?)
    }

    pub fn req_max_size(&self) -> Result<usize, Error> {
        #[derive(DekuRead)]
        #[deku(endian = "little")]
        struct ReqMaxSizeResponse {
            size: u16,
        }
        let resp = self.send(&gen_req(Func::ReqMaxSize, vec![])?)?;
        match ReqMaxSizeResponse::from_bytes((&resp, 0)) {
            Ok(((s, _), ret)) if s.len() == 0 => Ok(ret.size as usize),
            _ => Err(Error::PacketFormat),
        }
    }

    pub fn resp_max_size(&self) -> Result<usize, Error> {
        #[derive(DekuRead)]
        #[deku(endian = "little")]
        struct RespMaxSizeResponse {
            size: u16,
        }
        let resp = self.send(&gen_req(Func::RespMaxSize, vec![])?)?;
        match RespMaxSizeResponse::from_bytes((&resp, 0)) {
            Ok(((s, _), ret)) if s.len() == 0 => Ok(ret.size as usize),
            _ => Err(Error::PacketFormat),
        }
    }

    pub fn custom(&self, data: Vec<u8>) -> Result<Vec<u8>, Error> {
        self.send(&gen_req(Func::Custom, data)?)
    }
}