feat: implement parsing to data structures

This commit is contained in:
theo 2024-08-28 23:34:09 +02:00
parent c0bbdcf030
commit 6d9cd7fc14
Signed by: theo
SSH Key Fingerprint: SHA256:IbehMhSwpXrGUj7vj9iVvfdwe3g09IL9KLUz0zFzcXU

View File

@ -1,5 +1,5 @@
use bitvec::index::BitIdx; use bitvec::index::BitIdx;
use std::{error::Error, vec::Vec}; use std::{error::Error, str::FromStr, vec::Vec};
use deku::{ use deku::{
bitvec::{BitStore, Msb0}, bitvec::{BitStore, Msb0},
@ -10,7 +10,7 @@ use deku::{
}; };
#[deku_derive(DekuRead)] #[deku_derive(DekuRead)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] #[derive(Debug, Clone, Copy, PartialEq)]
#[deku(endian = "big")] #[deku(endian = "big")]
pub struct GroupId(u16); pub struct GroupId(u16);
@ -26,7 +26,7 @@ impl<T, E: Error> MapToDekuParseError<T> for Result<T, E> {
#[deku_derive(DekuRead)] #[deku_derive(DekuRead)]
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct DekuDataField { pub struct DataField {
#[deku(reader = "read_size(deku::reader)")] #[deku(reader = "read_size(deku::reader)")]
data_size: ByteSize, data_size: ByteSize,
@ -48,8 +48,8 @@ pub struct BlockHeader {
pub struct DataBlock { pub struct DataBlock {
pub header: BlockHeader, pub header: BlockHeader,
#[deku(bytes_read = "header.data_size.0")] #[deku(ctx = "header.group_id")]
pub data: Vec<DekuDataField>, pub inner: DataGroup,
} }
fn read_size<R: std::io::Read>(reader: &mut Reader<R>) -> Result<ByteSize, DekuError> { fn read_size<R: std::io::Read>(reader: &mut Reader<R>) -> Result<ByteSize, DekuError> {
@ -77,3 +77,81 @@ fn read_size<R: std::io::Read>(reader: &mut Reader<R>) -> Result<ByteSize, DekuE
false => Ok(ByteSize(first_byte as usize)), false => Ok(ByteSize(first_byte as usize)),
} }
} }
// Using this as the map function asks deku to parse a datafield
// We then use the datafield and convert it to the corresponding value
fn convert_from_data_field<T>(data_field: DataField) -> Result<T, DekuError>
where
T: FromStr,
T::Err: Error,
{
let text = String::from_utf8(data_field.data).map_to_deku_parse_error()?;
T::from_str(&text).map_to_deku_parse_error()
}
#[deku_derive(DekuRead)]
#[derive(Debug, PartialEq)]
pub struct SSVVersionNumber(#[deku(map = "convert_from_data_field")] u16);
#[deku_derive(DekuRead)]
#[derive(Debug, PartialEq)]
pub struct GALSSVersionNumber(#[deku(map = "convert_from_data_field")] u16);
#[deku_derive(DekuRead)]
#[derive(Debug, PartialEq)]
pub struct PSSVersionNumber(#[deku(map = "convert_from_data_field")] u16);
#[deku_derive(DekuRead)]
#[derive(Debug, PartialEq)]
pub struct ConfigurationHeader {
pub ssv_version: SSVVersionNumber,
pub galss_version: GALSSVersionNumber,
pub pss_version: PSSVersionNumber,
}
#[deku_derive(DekuRead)]
#[derive(Debug, PartialEq)]
pub struct PCSCReaderName(#[deku(map = "convert_from_data_field")] String);
#[deku_derive(DekuRead)]
#[derive(Debug, PartialEq)]
pub struct CardType(#[deku(map = "convert_from_data_field")] u8);
#[deku_derive(DekuRead)]
#[derive(Debug, PartialEq)]
pub struct PCSCReader {
pub name: PCSCReaderName,
pub card_type: CardType,
}
#[deku_derive(DekuRead)]
#[derive(Debug, PartialEq)]
pub struct SESAMVitaleComponentID(#[deku(map = "convert_from_data_field")] u16);
#[deku_derive(DekuRead)]
#[derive(Debug, PartialEq)]
pub struct SESAMVitaleComponentDescription(#[deku(map = "convert_from_data_field")] String);
#[deku_derive(DekuRead)]
#[derive(Debug, PartialEq)]
pub struct SESAMVitaleComponentVersion(#[deku(map = "convert_from_data_field")] String);
#[deku_derive(DekuRead)]
#[derive(Debug, PartialEq)]
pub struct SESAMVitaleComponent {
pub id: SESAMVitaleComponentID,
pub description: SESAMVitaleComponentDescription,
pub version: SESAMVitaleComponentVersion,
}
#[deku_derive(DekuRead)]
#[derive(Debug, PartialEq)]
#[deku(ctx = "group_id: GroupId", id = "group_id.0")]
pub enum DataGroup {
#[deku(id = 60)]
ConfigurationHeader(ConfigurationHeader),
#[deku(id = 67)]
PCSCReader(PCSCReader),
#[deku(id = 64)]
SESAMVitaleComponent(SESAMVitaleComponent),
}