Files
remote_marks/src/server/mod.rs
T

181 lines
5.3 KiB
Rust
Raw Normal View History

2026-09-15 23:41:39 +03:00
mod handling;
mod testing;
use litemap::LiteMap;
2026-09-16 12:19:07 +03:00
use minicbor::Decoder;
2026-09-15 10:38:03 +03:00
use minicbor::data::Type;
2026-09-15 23:41:39 +03:00
use minicbor::decode::Error;
use std::collections::HashMap;
2026-09-16 11:03:43 +03:00
use std::fmt::{Display, Formatter};
2026-09-15 23:41:39 +03:00
use std::io::Write;
2026-09-15 10:38:03 +03:00
2026-09-15 23:41:39 +03:00
pub enum Command {
2026-09-15 10:38:03 +03:00
Unknown,
2026-09-15 23:41:39 +03:00
Set(String, StoredData),
Define(String, LiteMap<String, StoredData>),
Push(String, StoredData),
2026-09-16 12:19:07 +03:00
Alias(String, String),
2026-09-15 23:41:39 +03:00
Display(String),
SetOutput(fn() -> Box<dyn Write>),
2026-09-15 10:38:03 +03:00
}
2026-09-15 23:41:39 +03:00
#[derive(Clone)]
pub enum StoredData {
Integer(isize),
Float(f64),
String(String),
Bool(bool),
Line(Line),
Vec(Vec<StoredData>),
2026-09-15 10:38:03 +03:00
}
2026-09-15 23:41:39 +03:00
impl Display for StoredData {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
StoredData::Integer(v) => v.fmt(f),
StoredData::Float(v) => v.fmt(f),
StoredData::String(v) => v.fmt(f),
StoredData::Bool(v) => v.fmt(f),
StoredData::Line(v) => v.fmt(f),
StoredData::Vec(vec) => {
2026-09-16 12:19:07 +03:00
vec.iter().enumerate().for_each(|(i, d)| {
write!(f, "{}", d).unwrap();
if i != vec.len() - 1 {
write!(f, "\n").unwrap();
}
2026-09-15 23:41:39 +03:00
});
Ok(())
}
}
}
}
#[derive(Clone)]
pub struct Line {
data: Vec<StoredData>,
}
impl From<Vec<StoredData>> for Line {
fn from(value: Vec<StoredData>) -> Self {
Self { data: value }
2026-09-15 10:38:03 +03:00
}
}
impl Display for Line {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2026-09-15 23:41:39 +03:00
write!(
f,
"[{}]",
self.data
.iter()
.map(|i| i.to_string())
.collect::<Vec<String>>()
.join(", ")
)
2026-09-15 10:38:03 +03:00
}
}
impl From<&[u8]> for Command {
fn from(value: &[u8]) -> Self {
2026-09-16 11:03:43 +03:00
parse_command(value).unwrap_or_else(|e| {
println!("{}", e);
Command::Unknown
})
2026-09-15 10:38:03 +03:00
}
}
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)?;
2026-09-15 23:41:39 +03:00
return Ok(Command::Set(id, value));
2026-09-15 22:35:36 +03:00
}
if data.starts_with(b"PUSH:") {
let payload = &data[b"PUSH:".len()..];
let mut decoder = Decoder::new(&payload);
2026-09-16 12:19:07 +03:00
_ = decoder.array()?;
2026-09-15 22:35:36 +03:00
let id = decoder.str()?.to_string();
let value = decode_value(&mut decoder)?;
2026-09-15 23:41:39 +03:00
return Ok(Command::Push(id, value));
}
if data.starts_with(b"DISPLAY:") {
let payload = &data[b"DISPLAY:".len()..];
let mut decoder = Decoder::new(&payload);
decoder.array()?;
let id = decoder.str()?.to_string();
return Ok(Command::Display(id));
2026-09-15 10:38:03 +03:00
}
2026-09-16 12:19:07 +03:00
if data.starts_with(b"ALIAS:") {
let payload = &data[b"ALIAS:".len()..];
let mut decoder = Decoder::new(&payload);
decoder.array()?;
let id = decoder.str()?.to_string();
let alias = decoder.str()?.to_string();
return Ok(Command::Alias(id, alias));
}
2026-09-15 10:38:03 +03:00
Ok(Command::Unknown)
}
2026-09-15 23:41:39 +03:00
fn decode_value(decoder: &mut Decoder) -> Result<StoredData, Error> {
2026-09-15 10:38:03 +03:00
Ok(match decoder.datatype()? {
2026-09-15 23:41:39 +03:00
Type::Bool => StoredData::Bool(decoder.bool()?),
Type::U8 => StoredData::Integer(decoder.u8()? as isize),
Type::U16 => StoredData::Integer(decoder.u16()? as isize),
Type::U32 => StoredData::Integer(decoder.u32()? as isize),
Type::U64 => StoredData::Integer(decoder.u64()? as isize),
Type::I8 => StoredData::Integer(decoder.i8()? as isize),
Type::I16 => StoredData::Integer(decoder.i16()? as isize),
Type::I32 => StoredData::Integer(decoder.i32()? as isize),
Type::I64 => StoredData::Integer(decoder.i64()? as isize),
Type::Int => StoredData::Integer(decoder.i32()? as isize),
Type::F16 => StoredData::Float(decoder.f32()? as f64),
Type::F32 => StoredData::Float(decoder.f32()? as f64),
Type::F64 => StoredData::Float(decoder.f64()?),
Type::String | Type::StringIndef => StoredData::String(decoder.str()?.to_string()),
Type::Array | Type::ArrayIndef => {
2026-09-15 10:38:03 +03:00
let len = decoder.array()?;
2026-09-15 23:41:39 +03:00
let mut array = if let Some(len) = len {
Vec::with_capacity(len as usize)
} else {
vec![]
};
2026-09-16 12:19:07 +03:00
if array.capacity() == 0 {
2026-09-15 10:38:03 +03:00
loop {
let dt = decoder.datatype()?;
if let Type::Break = dt {
break;
}
array.push(decode_value(decoder)?);
}
2026-09-16 12:19:07 +03:00
} else {
for _ in 0..array.capacity() {
array.push(decode_value(decoder)?);
}
2026-09-15 10:38:03 +03:00
}
2026-09-15 23:41:39 +03:00
StoredData::Line(Line::from(array))
}
_ => {
decoder.skip()?;
StoredData::Bool(false)
2026-09-15 10:38:03 +03:00
}
})
}
2026-09-15 23:41:39 +03:00
pub struct NoteContext {
entries: HashMap<String, StoredData>,
2026-09-16 12:19:07 +03:00
aliases: HashMap<String, String>,
2026-09-15 23:41:39 +03:00
output: Box<dyn Write>,
}
impl NoteContext {
pub fn default() -> Self {
2026-09-16 11:03:43 +03:00
Self {
2026-09-15 23:41:39 +03:00
entries: Default::default(),
2026-09-16 12:19:07 +03:00
aliases: Default::default(),
2026-09-15 23:41:39 +03:00
output: Box::new(std::io::stdout()),
}
}
}