89 lines
2.7 KiB
Rust
89 lines
2.7 KiB
Rust
use minicbor::decode::Error;
|
|||
|
|
use minicbor::Decoder;
|
||
|
|
use std::any::Any;
|
||
|
|
use std::collections::HashMap;
|
||
|
|
use std::fmt::{Debug, Display, Formatter};
|
||
|
|
use minicbor::data::Type;
|
||
|
|
|
||
|
|
enum Command {
|
||
|
|
Unknown,
|
||
|
|
Define(String, Box<dyn Display>),
|
||
|
|
Set(String, Box<dyn Display>),
|
||
|
|
Push(String, Box<dyn Display>),
|
||
|
|
}
|
||
|
|
|
||
|
|
struct Line{
|
||
|
|
data: Vec<Box<dyn Display>>,
|
||
|
|
}
|
||
|
|
|
||
|
|
impl From<Vec<Box<dyn Display>>> for Line {
|
||
|
|
fn from(value: Vec<Box<dyn Display>>) -> Self {
|
||
|
|
Self{data: value}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
impl Display for Line {
|
||
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||
|
|
write!(f, "[{}]", self.data.iter().map(|i| i.to_string()).collect::<Vec<String>>().join(", "))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
impl From<&[u8]> for Command {
|
||
|
|
fn from(value: &[u8]) -> Self {
|
||
|
|
parse_command(value).unwrap_or(Command::Unknown)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
fn parse_command(data: &[u8]) -> Result<Command, Error> {
|
||
|
|
if data.starts_with(b"SET:") {
|
||
|
|
let payload = &data[b"SET:".len()..];
|
||
|
|
let mut decoder = Decoder::new(&payload);
|
||
|
|
decoder.array()?;
|
||
|
|
let id = decoder.str()?.to_string();
|
||
|
|
let value = decode_value(&mut decoder)?;
|
||
|
|
}
|
||
|
|
Ok(Command::Unknown)
|
||
|
|
}
|
||
|
|
|
||
|
|
fn decode_value(decoder: &mut Decoder) -> Result<Box<dyn Display>, Error> {
|
||
|
|
Ok(match decoder.datatype()? {
|
||
|
|
Type::Bool => Box::new(decoder.bool()?),
|
||
|
|
Type::U8 => Box::new(decoder.u8()? as isize),
|
||
|
|
Type::U16 => Box::new(decoder.u16()? as isize),
|
||
|
|
Type::U32 => Box::new(decoder.u32()? as isize),
|
||
|
|
Type::U64 => Box::new(decoder.u64()? as isize),
|
||
|
|
Type::I8 => Box::new(decoder.i8()? as isize),
|
||
|
|
Type::I16 => Box::new(decoder.i16()? as isize),
|
||
|
|
Type::I32 => Box::new(decoder.i32()? as isize),
|
||
|
|
Type::I64 => Box::new(decoder.i64()? as isize),
|
||
|
|
Type::Int => Box::new(decoder.i32()? as isize),
|
||
|
|
Type::F16 => Box::new(decoder.f32()? as f64),
|
||
|
|
Type::F32 => Box::new(decoder.f32()? as f64),
|
||
|
|
Type::F64 => Box::new(decoder.f64()?),
|
||
|
|
Type::String |
|
||
|
|
Type::StringIndef => Box::new(decoder.str()?.to_string()),
|
||
|
|
Type::Array |
|
||
|
|
Type::ArrayIndef => {
|
||
|
|
let len = decoder.array()?;
|
||
|
|
let mut array = if let Some(len) = len { Vec::with_capacity(len as usize) } else { vec![] };
|
||
|
|
if array.is_empty() {
|
||
|
|
loop {
|
||
|
|
let dt = decoder.datatype()?;
|
||
|
|
if let Type::Break = dt {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
array.push(decode_value(decoder)?);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
Box::new(Line::from(array))
|
||
|
|
}
|
||
|
|
// Type::Tag => {
|
||
|
|
// let tag = decoder.tag()?;
|
||
|
|
// }
|
||
|
|
_ => Box::new(false)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
struct NoteContext {
|
||
|
|
entries: HashMap<String, Box<dyn Any>>,
|
||
|
|
}
|