use std::io::Write;
use wasm_bindgen::prelude::*;
use crate::types::{MsgValue, MsgPackEntry, MsgPackValue};
#[wasm_bindgen]
pub fn pack_json(json: &str) -> Vec<u8> {
let mut buffer: Vec<u8> = vec![];
let entry: MsgPackEntry = serde_json::from_str(json).unwrap();
write_value(&mut buffer, &entry.data).unwrap();
buffer
}
pub fn pack(entry: &MsgPackEntry) -> Vec<u8> {
let mut buffer: Vec<u8> = vec![];
write_value(&mut buffer, &entry.data).unwrap();
buffer
}
pub fn write_value<W: Write, V: MsgValue>(writer: &mut W, value: &V) -> std::io::Result<()> {
match value.get_value() {
MsgPackValue::Null => {
writer.write_all(&[0xC0])?;
},
MsgPackValue::Bool(b) => {
writer.write_all(&[if !*b { 0xC2 } else { 0xC3 }])?;
},
MsgPackValue::FixPos(n) => {
writer.write_all(&[(*n) & 0b0111_1111])?; },
MsgPackValue::FixNeg(n) => {
writer.write_all(&[(*n as u8) & 0b0001_1111 | 0b1110_0000])?; },
MsgPackValue::U8(n) => {
writer.write_all(&[0xCC])?;
writer.write_all(&[*n])?;
},
MsgPackValue::U16(n) => {
writer.write_all(&[0xCD])?;
writer.write_all(&(*n).to_be_bytes())?;
},
MsgPackValue::U32(n) => {
writer.write_all(&[0xCE])?;
writer.write_all(&(*n).to_be_bytes())?;
},
MsgPackValue::U64(n) => {
writer.write_all(&[0xCF])?;
writer.write_all(&(*n).to_be_bytes())?;
},
MsgPackValue::I8(n) => {
writer.write_all(&[0xD0])?;
writer.write_all(&[*n as u8])?;
},
MsgPackValue::I16(n) => {
writer.write_all(&[0xD1])?;
writer.write_all(&(*n).to_be_bytes())?;
},
MsgPackValue::I32(n) => {
writer.write_all(&[0xD2])?;
writer.write_all(&(*n).to_be_bytes())?;
},
MsgPackValue::I64(n) => {
writer.write_all(&[0xD3])?;
writer.write_all(&(*n).to_be_bytes())?;
},
MsgPackValue::F32(n) => {
writer.write_all(&[0xCA])?;
writer.write_all(&(*n).to_be_bytes())?;
},
MsgPackValue::F64(n) => {
writer.write_all(&[0xCB])?;
writer.write_all(&(*n).to_be_bytes())?;
},
MsgPackValue::FixStr(s) => {
let bytes = s.as_bytes();
writer.write_all(&[(bytes.len() as u8) & 0b0001_1111 | 0b1010_0000])?; writer.write_all(bytes)?;
},
MsgPackValue::Str8(s) => {
let bytes = s.as_bytes();
writer.write_all(&[0xD9])?;
writer.write_all(&[bytes.len() as u8])?;
writer.write_all(bytes)?;
},
MsgPackValue::Str16(s) => {
let bytes = s.as_bytes();
writer.write_all(&[0xDA])?;
writer.write_all(&(bytes.len() as u16).to_be_bytes())?;
writer.write_all(bytes)?;
},
MsgPackValue::Str32(s) => {
let bytes = s.as_bytes();
writer.write_all(&[0xDB])?;
writer.write_all(&(bytes.len() as u32).to_be_bytes())?;
writer.write_all(bytes)?;
},
MsgPackValue::Bin8(b) => {
writer.write_all(&[0xC4])?;
writer.write_all(&[b.len() as u8])?;
writer.write_all(b)?;
},
MsgPackValue::Bin16(b) => {
writer.write_all(&[0xC5])?;
writer.write_all(&(b.len() as u16).to_be_bytes())?;
writer.write_all(b)?;
},
MsgPackValue::Bin32(b) => {
writer.write_all(&[0xC6])?;
writer.write_all(&(b.len() as u32).to_be_bytes())?;
writer.write_all(b)?;
},
MsgPackValue::FixArray(values) => {
writer.write_all(&[(values.len() as u8) & 0b0000_1111 | 0b1001_0000])?;
for v in values {
write_value(writer, &v.data)?;
}
},
MsgPackValue::Array16(values) => {
writer.write_all(&[0xDC])?;
writer.write_all(&(values.len() as u16).to_be_bytes())?;
for v in values {
write_value(writer, &v.data)?;
}
},
MsgPackValue::Array32(values) => {
writer.write_all(&[0xDD])?;
writer.write_all(&(values.len() as u32).to_be_bytes())?;
for v in values {
write_value(writer, &v.data)?;
}
},
MsgPackValue::FixMap(values) => {
writer.write_all(&[(values.len() as u8) & 0b0000_1111 | 0b1000_0000])?;
for (k, v) in values {
write_value(writer, &k.data)?;
write_value(writer, &v.data)?;
}
},
MsgPackValue::Map16(values) => {
writer.write_all(&[0xDE])?;
writer.write_all(&(values.len() as u16).to_be_bytes())?;
for (k, v) in values {
write_value(writer, &k.data)?;
write_value(writer, &v.data)?;
}
},
MsgPackValue::Map32(values) => {
writer.write_all(&[0xDF])?;
writer.write_all(&(values.len() as u32).to_be_bytes())?;
for (k, v) in values {
write_value(writer, &k.data)?;
write_value(writer, &v.data)?;
}
}
}
Ok(())
}