formaty/src/formatter/format.rs

67 lines
1.7 KiB
Rust

use crate::byte_stream::ByteStream;
use serde::Deserialize;
use std::fmt::Write;
#[derive(Debug, Deserialize, Clone)]
#[serde(tag = "type")]
pub enum FieldType {
/// Unsigned Int
UInt { bit_width: usize },
/// Unsigned Int
Int { bit_width: usize },
/// Null Terminated String Field
String { max_len: usize },
/// Fixed Byte Length Field
Bytes { max_len: usize },
}
#[derive(Debug, Deserialize, Clone)]
pub struct Field {
/// Field Name
pub name: String,
/// Field Type
pub field_type: FieldType,
}
impl Field {
fn format_data(&self, byte_stream: &ByteStream, bit_ndx: usize) -> (String, usize) {
match self.field_type {
FieldType::UInt { bit_width } => {
let bytes = byte_stream.get_bytes(bit_ndx, bit_width).unwrap();
let mut string = String::with_capacity(bytes.len() * 2);
for byte in bytes.iter().rev() {
string.push_str(&format!("{:x}", byte))
}
(string, bit_width)
}
_ => ("".to_string(), 0),
}
}
}
#[derive(Debug, Deserialize, Clone)]
pub struct Format {
/// Format Name
pub name: String,
/// Elements of the format
pub fields: Vec<Field>,
}
impl Format {
pub fn format_data(&self, data: &[u8]) -> String {
let mut s = String::new();
let byte_stream = ByteStream::from(data);
let mut bit_ndx: usize = 0;
for field in &self.fields {
let (data_str, bit_width) = field.format_data(&byte_stream, bit_ndx);
bit_ndx += bit_width;
writeln!(s, "{}: {}", field.name, data_str).unwrap();
}
s
}
}