//! 数据成帧器

use crate::consts::*;
use crate::frame::*;
use crc16;
use heapless::Vec;

/// 成帧器
pub struct Writer {
    /// 帧
    buf: Vec<u8, FrameLen>,
    /// 前导长度
    lead_len: usize,
}
impl Writer {
    /// 创建一个成帧器
    pub fn new(lead_len: usize) -> Self {
        Self {
            buf: Vec::new(),
            lead_len: lead_len,
        }
    }
    pub fn get_frame(&mut self, load: &[u8]) -> &[u8] {
        let load_len = load.len();
        if load_len > LOAD_LEN {
            return &[];
        }
        // 设置校验
        let check = crc16::State::<crc16::MODBUS>::calculate(load);
        let frame = &mut self.buf;
        frame.clear();
        for _ in 0..self.lead_len {
            frame.push(CHAR_LEAD).unwrap();
        }
        frame.push(CHAR_START).unwrap();
        frame
            .extend_from_slice(&[(load_len >> 8) as u8, load_len as u8])
            .unwrap();
        frame.extend_from_slice(load).unwrap();
        frame
            .extend_from_slice(&[(check >> 8) as u8, check as u8])
            .unwrap();
        frame.push(CHAR_END).unwrap();
        return frame;
    }
}
