mirror of
https://github.com/Noratrieb/haesli.git
synced 2026-01-14 19:55:03 +01:00
table ser
This commit is contained in:
parent
cb3710cd3f
commit
427cfadc11
4 changed files with 1347 additions and 1251 deletions
|
|
@ -2,10 +2,10 @@ mod parser;
|
||||||
mod write;
|
mod write;
|
||||||
|
|
||||||
use crate::parser::codegen_parser;
|
use crate::parser::codegen_parser;
|
||||||
|
use crate::write::codegen_write;
|
||||||
use heck::ToUpperCamelCase;
|
use heck::ToUpperCamelCase;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use strong_xml::XmlRead;
|
use strong_xml::XmlRead;
|
||||||
use crate::write::codegen_write;
|
|
||||||
|
|
||||||
#[derive(Debug, XmlRead)]
|
#[derive(Debug, XmlRead)]
|
||||||
#[xml(tag = "amqp")]
|
#[xml(tag = "amqp")]
|
||||||
|
|
@ -151,8 +151,9 @@ fn amqp_type_to_rust_type(amqp_type: &str) -> &'static str {
|
||||||
"short" => "u16",
|
"short" => "u16",
|
||||||
"long" => "u32",
|
"long" => "u32",
|
||||||
"longlong" => "u64",
|
"longlong" => "u64",
|
||||||
"bit" => "u8",
|
"bit" => "bool",
|
||||||
"shortstr" | "longstr" => "String",
|
"shortstr" => "String",
|
||||||
|
"longstr" => "Vec<u8>",
|
||||||
"timestamp" => "u64",
|
"timestamp" => "u64",
|
||||||
"table" => "super::Table",
|
"table" => "super::Table",
|
||||||
_ => unreachable!("invalid type {}", amqp_type),
|
_ => unreachable!("invalid type {}", amqp_type),
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -6,7 +6,9 @@ mod generated;
|
||||||
mod parse_helper;
|
mod parse_helper;
|
||||||
mod write_helper;
|
mod write_helper;
|
||||||
|
|
||||||
pub type Table = HashMap<String, FieldValue>;
|
pub type TableFieldName = String;
|
||||||
|
|
||||||
|
pub type Table = HashMap<TableFieldName, FieldValue>;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum FieldValue {
|
pub enum FieldValue {
|
||||||
|
|
@ -22,8 +24,8 @@ pub enum FieldValue {
|
||||||
Float(f32),
|
Float(f32),
|
||||||
Double(f64),
|
Double(f64),
|
||||||
DecimalValue(u8, u32),
|
DecimalValue(u8, u32),
|
||||||
ShortString(String),
|
ShortString(Shortstr),
|
||||||
LongString(String),
|
LongString(Longstr),
|
||||||
FieldArray(Vec<FieldValue>),
|
FieldArray(Vec<FieldValue>),
|
||||||
Timestamp(u64),
|
Timestamp(u64),
|
||||||
FieldTable(Table),
|
FieldTable(Table),
|
||||||
|
|
|
||||||
|
|
@ -1,47 +1,193 @@
|
||||||
use crate::classes::generated::{
|
use crate::classes::generated::{
|
||||||
Bit, Long, Longlong, Longstr, Octet, Short, Shortstr, Table, Timestamp,
|
Bit, Long, Longlong, Longstr, Octet, Short, Shortstr, Table, Timestamp,
|
||||||
};
|
};
|
||||||
|
use crate::classes::{FieldValue, TableFieldName};
|
||||||
use crate::error::TransError;
|
use crate::error::TransError;
|
||||||
|
use anyhow::Context;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
fn error(e: io::Error) -> TransError {
|
|
||||||
TransError::Other(e.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn octet<W: Write>(value: Octet, writer: &mut W) -> Result<(), TransError> {
|
pub fn octet<W: Write>(value: Octet, writer: &mut W) -> Result<(), TransError> {
|
||||||
writer.write_all(&[value])?;
|
writer.write_all(&[value])?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn short<W: Write>(value: Short, writer: &mut W) -> Result<(), TransError> {
|
pub fn short<W: Write>(value: Short, writer: &mut W) -> Result<(), TransError> {
|
||||||
todo!()
|
writer.write_all(&value.to_be_bytes())?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn long<W: Write>(value: Long, writer: &mut W) -> Result<(), TransError> {
|
pub fn long<W: Write>(value: Long, writer: &mut W) -> Result<(), TransError> {
|
||||||
todo!()
|
writer.write_all(&value.to_be_bytes())?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn longlong<W: Write>(value: Longlong, writer: &mut W) -> Result<(), TransError> {
|
pub fn longlong<W: Write>(value: Longlong, writer: &mut W) -> Result<(), TransError> {
|
||||||
todo!()
|
writer.write_all(&value.to_be_bytes())?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bit<W: Write>(value: Vec<Bit>, writer: &mut W) -> Result<(), TransError> {
|
pub fn bit<W: Write>(value: Vec<Bit>, writer: &mut W) -> Result<(), TransError> {
|
||||||
todo!()
|
// accumulate bits into bytes, starting from the least significant bit in each byte
|
||||||
|
|
||||||
|
// how many bits have already been packed into `current_buf`
|
||||||
|
let mut already_filled = 0;
|
||||||
|
let mut current_buf = 0u8;
|
||||||
|
|
||||||
|
for bit in value {
|
||||||
|
if already_filled >= 8 {
|
||||||
|
writer.write_all(&[current_buf])?;
|
||||||
|
current_buf = 0;
|
||||||
|
already_filled = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_bit = (u8::from(bit)) << already_filled;
|
||||||
|
current_buf |= new_bit;
|
||||||
|
already_filled += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if already_filled > 0 {
|
||||||
|
writer.write_all(&[current_buf])?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shortstr<W: Write>(value: Shortstr, writer: &mut W) -> Result<(), TransError> {
|
pub fn shortstr<W: Write>(value: Shortstr, writer: &mut W) -> Result<(), TransError> {
|
||||||
todo!()
|
let len = u8::try_from(value.len()).context("shortstr too long")?;
|
||||||
|
writer.write_all(&[len])?;
|
||||||
|
writer.write_all(value.as_bytes())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn longstr<W: Write>(value: Longstr, writer: &mut W) -> Result<(), TransError> {
|
pub fn longstr<W: Write>(value: Longstr, writer: &mut W) -> Result<(), TransError> {
|
||||||
todo!()
|
let len = u32::try_from(value.len()).context("longstr too long")?;
|
||||||
|
writer.write_all(&len.to_be_bytes())?;
|
||||||
|
writer.write_all(value.as_slice())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn timestamp<W: Write>(value: Timestamp, writer: &mut W) -> Result<(), TransError> {
|
pub fn timestamp<W: Write>(value: Timestamp, writer: &mut W) -> Result<(), TransError> {
|
||||||
todo!()
|
writer.write_all(&value.to_be_bytes())?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn table<W: Write>(value: Table, writer: &mut W) -> Result<(), TransError> {
|
pub fn table<W: Write>(table: Table, writer: &mut W) -> Result<(), TransError> {
|
||||||
todo!()
|
let len = u32::try_from(table.len()).context("table too big")?;
|
||||||
|
writer.write_all(&len.to_be_bytes())?;
|
||||||
|
|
||||||
|
for (field_name, value) in table {
|
||||||
|
shortstr(field_name, writer)?;
|
||||||
|
field_value(value, writer)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn field_value<W: Write>(value: FieldValue, writer: &mut W) -> Result<(), TransError> {
|
||||||
|
match value {
|
||||||
|
FieldValue::Boolean(bool) => {
|
||||||
|
writer.write_all(&[b't', u8::from(bool)])?;
|
||||||
|
}
|
||||||
|
FieldValue::ShortShortInt(int) => {
|
||||||
|
writer.write_all(b"b")?;
|
||||||
|
writer.write_all(&int.to_be_bytes())?;
|
||||||
|
}
|
||||||
|
FieldValue::ShortShortUInt(int) => {
|
||||||
|
writer.write_all(&[b'B', int])?;
|
||||||
|
}
|
||||||
|
FieldValue::ShortInt(int) => {
|
||||||
|
writer.write_all(b"U")?;
|
||||||
|
writer.write_all(&int.to_be_bytes())?;
|
||||||
|
}
|
||||||
|
FieldValue::ShortUInt(int) => {
|
||||||
|
writer.write_all(b"u")?;
|
||||||
|
writer.write_all(&int.to_be_bytes())?;
|
||||||
|
}
|
||||||
|
FieldValue::LongInt(int) => {
|
||||||
|
writer.write_all(b"I")?;
|
||||||
|
writer.write_all(&int.to_be_bytes())?;
|
||||||
|
}
|
||||||
|
FieldValue::LongUInt(int) => {
|
||||||
|
writer.write_all(b"i")?;
|
||||||
|
writer.write_all(&int.to_be_bytes())?;
|
||||||
|
}
|
||||||
|
FieldValue::LongLongInt(int) => {
|
||||||
|
writer.write_all(b"L")?;
|
||||||
|
writer.write_all(&int.to_be_bytes())?;
|
||||||
|
}
|
||||||
|
FieldValue::LongLongUInt(int) => {
|
||||||
|
writer.write_all(b"l")?;
|
||||||
|
writer.write_all(&int.to_be_bytes())?;
|
||||||
|
}
|
||||||
|
FieldValue::Float(float) => {
|
||||||
|
writer.write_all(b"f")?;
|
||||||
|
writer.write_all(&float.to_be_bytes())?;
|
||||||
|
}
|
||||||
|
FieldValue::Double(float) => {
|
||||||
|
writer.write_all(b"d")?;
|
||||||
|
writer.write_all(&float.to_be_bytes())?;
|
||||||
|
}
|
||||||
|
FieldValue::DecimalValue(scale, long) => {
|
||||||
|
writer.write_all(&[b'D', scale])?;
|
||||||
|
writer.write_all(&long.to_be_bytes())?;
|
||||||
|
}
|
||||||
|
FieldValue::ShortString(str) => {
|
||||||
|
writer.write_all(b"s")?;
|
||||||
|
shortstr(str, writer)?;
|
||||||
|
}
|
||||||
|
FieldValue::LongString(str) => {
|
||||||
|
writer.write_all(b"S")?;
|
||||||
|
longstr(str, writer)?;
|
||||||
|
}
|
||||||
|
FieldValue::FieldArray(array) => {
|
||||||
|
writer.write_all(b"A")?;
|
||||||
|
let len = u32::try_from(array.len()).context("array too long")?;
|
||||||
|
writer.write_all(&len.to_be_bytes())?;
|
||||||
|
|
||||||
|
for element in array {
|
||||||
|
field_value(element, writer)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FieldValue::Timestamp(time) => {
|
||||||
|
writer.write_all(b"T")?;
|
||||||
|
writer.write_all(&time.to_be_bytes())?;
|
||||||
|
}
|
||||||
|
FieldValue::FieldTable(_) => {
|
||||||
|
writer.write_all(b"F")?;
|
||||||
|
}
|
||||||
|
FieldValue::Void => {
|
||||||
|
writer.write_all(b"V")?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[test]
|
||||||
|
fn pack_few_bits() {
|
||||||
|
let bits = vec![true, false, true];
|
||||||
|
|
||||||
|
let mut buffer = [0u8; 1];
|
||||||
|
super::bit(bits, &mut buffer.as_mut_slice()).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(buffer, [0b00000101])
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pack_many_bits() {
|
||||||
|
let bits = vec![
|
||||||
|
/* first 8 */
|
||||||
|
true, true, true, true, false, false, false, false, /* second 4 */
|
||||||
|
true, false, true, true,
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut buffer = [0u8; 2];
|
||||||
|
super::bit(bits, &mut buffer.as_mut_slice()).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(buffer, [0b00001111, 0b00001101]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue