pub use super::OctetStr;
use super::{
map, take, take_byte,
tlf::{Ty, TypeLengthField},
NumberFormatter, OctetStrFormatter, ParseError, ResTy, SmlParse, SmlParseTlf,
};
#[derive(PartialEq, Eq, Clone)]
pub struct OpenResponse<'i> {
pub codepage: Option<OctetStr<'i>>,
pub client_id: Option<OctetStr<'i>>,
pub req_file_id: OctetStr<'i>,
pub server_id: OctetStr<'i>,
pub ref_time: Option<Time>,
pub sml_version: Option<u8>,
}
impl<'i> SmlParseTlf<'i> for OpenResponse<'i> {
fn check_tlf(tlf: &TypeLengthField) -> bool {
*tlf == TypeLengthField::new(Ty::ListOf, 6usize as u32)
}
fn parse_with_tlf(input: &'i [u8], _tlf: &TypeLengthField) -> ResTy<'i, Self> {
let (input, codepage) = <Option<OctetStr<'i>>>::parse(input)?;
let (input, client_id) = <Option<OctetStr<'i>>>::parse(input)?;
let (input, req_file_id) = <OctetStr<'i>>::parse(input)?;
let (input, server_id) = <OctetStr<'i>>::parse(input)?;
let (input, ref_time) = <Option<Time>>::parse(input)?;
let (input, sml_version) = <Option<u8>>::parse(input)?;
let val = OpenResponse {
codepage,
client_id,
req_file_id,
server_id,
ref_time,
sml_version,
};
Ok((input, val))
}
}
impl<'i> core::fmt::Debug for OpenResponse<'i> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let mut x = f.debug_struct("OpenResponse");
if let Some(e) = &self.codepage {
x.field("codepage", &OctetStrFormatter(e));
}
if let Some(e) = &self.client_id {
x.field("client_id", &OctetStrFormatter(e));
}
x.field("req_file_id", &OctetStrFormatter(self.req_file_id));
x.field("server_id", &OctetStrFormatter(self.server_id));
if let Some(e) = &self.ref_time {
x.field("ref_time", &e);
}
if let Some(e) = &self.sml_version {
x.field("sml_version", &e);
}
x.finish()
}
}
#[derive(PartialEq, Eq, Clone)]
pub struct ListEntry<'i> {
pub obj_name: OctetStr<'i>,
pub status: Option<Status>,
pub val_time: Option<Time>,
pub unit: Option<Unit>,
pub scaler: Option<i8>,
pub value: Value<'i>,
pub value_signature: Option<Signature<'i>>,
}
impl<'i> SmlParseTlf<'i> for ListEntry<'i> {
fn check_tlf(tlf: &TypeLengthField) -> bool {
*tlf == TypeLengthField::new(Ty::ListOf, 7usize as u32)
}
fn parse_with_tlf(input: &'i [u8], _tlf: &TypeLengthField) -> ResTy<'i, Self> {
let (input, obj_name) = <OctetStr<'i>>::parse(input)?;
let (input, status) = <Option<Status>>::parse(input)?;
let (input, val_time) = <Option<Time>>::parse(input)?;
let (input, unit) = <Option<Unit>>::parse(input)?;
let (input, scaler) = <Option<i8>>::parse(input)?;
let (input, value) = <Value<'i>>::parse(input)?;
let (input, value_signature) = <Option<Signature<'i>>>::parse(input)?;
let val = ListEntry {
obj_name,
status,
val_time,
unit,
scaler,
value,
value_signature,
};
Ok((input, val))
}
}
impl<'i> core::fmt::Debug for ListEntry<'i> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let mut x = f.debug_struct("ListEntry");
x.field("obj_name", &OctetStrFormatter(self.obj_name));
if let Some(e) = &self.status {
x.field("status", &e);
}
if let Some(e) = &self.val_time {
x.field("val_time", &e);
}
if let Some(e) = &self.unit {
x.field("unit", &e);
}
if let Some(e) = &self.scaler {
x.field("scaler", &e);
}
x.field("value", &self.value);
if let Some(e) = &self.value_signature {
x.field("value_signature", &e);
}
x.finish()
}
}
#[derive(PartialEq, Eq, Clone)]
#[allow(missing_docs)]
pub enum Value<'i> {
Bool(bool),
Bytes(OctetStr<'i>),
I8(i8),
I16(i16),
I32(i32),
I64(i64),
U8(u8),
U16(u16),
U32(u32),
U64(u64),
List(ListType),
}
impl<'i> SmlParseTlf<'i> for Value<'i> {
fn check_tlf(_tlf: &TypeLengthField) -> bool {
true
}
fn parse_with_tlf(input: &'i [u8], tlf: &TypeLengthField) -> ResTy<'i, Self> {
match tlf {
tlf if <bool>::check_tlf(tlf) => map(<bool>::parse_with_tlf(input, tlf), Self::Bool),
tlf if <OctetStr<'i>>::check_tlf(tlf) => {
map(<OctetStr<'i>>::parse_with_tlf(input, tlf), Self::Bytes)
}
tlf if <i8>::check_tlf(tlf) => map(<i8>::parse_with_tlf(input, tlf), Self::I8),
tlf if <i16>::check_tlf(tlf) => map(<i16>::parse_with_tlf(input, tlf), Self::I16),
tlf if <i32>::check_tlf(tlf) => map(<i32>::parse_with_tlf(input, tlf), Self::I32),
tlf if <i64>::check_tlf(tlf) => map(<i64>::parse_with_tlf(input, tlf), Self::I64),
tlf if <u8>::check_tlf(tlf) => map(<u8>::parse_with_tlf(input, tlf), Self::U8),
tlf if <u16>::check_tlf(tlf) => map(<u16>::parse_with_tlf(input, tlf), Self::U16),
tlf if <u32>::check_tlf(tlf) => map(<u32>::parse_with_tlf(input, tlf), Self::U32),
tlf if <u64>::check_tlf(tlf) => map(<u64>::parse_with_tlf(input, tlf), Self::U64),
tlf if <ListType>::check_tlf(tlf) => {
map(<ListType>::parse_with_tlf(input, tlf), Self::List)
}
_ => Err(ParseError::TlfMismatch(core::any::type_name::<Self>())),
}
}
}
impl<'i> core::fmt::Debug for Value<'i> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Bool(arg0) => write!(f, "{:?}", arg0),
Self::Bytes(arg0) => write!(f, "{:?}", OctetStrFormatter(arg0)),
Self::I8(arg0) => write!(f, "{:?}", NumberFormatter(arg0)),
Self::I16(arg0) => write!(f, "{:?}", NumberFormatter(arg0)),
Self::I32(arg0) => write!(f, "{:?}", NumberFormatter(arg0)),
Self::I64(arg0) => write!(f, "{:?}", NumberFormatter(arg0)),
Self::U8(arg0) => write!(f, "{:?}", NumberFormatter(arg0)),
Self::U16(arg0) => write!(f, "{:?}", NumberFormatter(arg0)),
Self::U32(arg0) => write!(f, "{:?}", NumberFormatter(arg0)),
Self::U64(arg0) => write!(f, "{:?}", NumberFormatter(arg0)),
Self::List(arg0) => write!(f, "{:?}", arg0),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum ListType {
Time(Time),
}
impl<'i> SmlParseTlf<'i> for ListType {
fn check_tlf(tlf: &TypeLengthField) -> bool {
tlf.ty == Ty::ListOf && tlf.len == 2
}
fn parse_with_tlf(input: &'i [u8], _tlf: &TypeLengthField) -> ResTy<'i, Self> {
let (input, tag) = u8::parse(input)?;
match tag {
1 => {
let (input, x) = <Time>::parse(input)?;
Ok((input, ListType::Time(x)))
}
_ => Err(ParseError::UnexpectedVariant),
}
}
}
#[derive(PartialEq, Eq, Clone)]
pub enum Status {
Status8(u8),
Status16(u16),
Status32(u32),
Status64(u64),
}
impl<'i> SmlParseTlf<'i> for Status {
fn check_tlf(_tlf: &TypeLengthField) -> bool {
true
}
fn parse_with_tlf(input: &'i [u8], tlf: &TypeLengthField) -> ResTy<'i, Self> {
match tlf {
tlf if <u8>::check_tlf(tlf) => map(<u8>::parse_with_tlf(input, tlf), Self::Status8),
tlf if <u16>::check_tlf(tlf) => map(<u16>::parse_with_tlf(input, tlf), Self::Status16),
tlf if <u32>::check_tlf(tlf) => map(<u32>::parse_with_tlf(input, tlf), Self::Status32),
tlf if <u64>::check_tlf(tlf) => map(<u64>::parse_with_tlf(input, tlf), Self::Status64),
_ => Err(ParseError::TlfMismatch(core::any::type_name::<Self>())),
}
}
}
impl ::core::fmt::Debug for Status {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Status8(x) => write!(f, "{:?}", NumberFormatter(x)),
Self::Status16(x) => write!(f, "{:?}", NumberFormatter(x)),
Self::Status32(x) => write!(f, "{:?}", NumberFormatter(x)),
Self::Status64(x) => write!(f, "{:?}", NumberFormatter(x)),
}
}
}
pub type Unit = u8;
#[derive(PartialEq, Eq, Clone)]
pub struct CloseResponse<'i> {
pub global_signature: Option<Signature<'i>>,
}
impl<'i> SmlParseTlf<'i> for CloseResponse<'i> {
fn check_tlf(tlf: &TypeLengthField) -> bool {
*tlf == TypeLengthField::new(Ty::ListOf, 1usize as u32)
}
fn parse_with_tlf(input: &'i [u8], _tlf: &TypeLengthField) -> ResTy<'i, Self> {
let (input, global_signature) = <Option<Signature<'i>>>::parse(input)?;
let val = CloseResponse { global_signature };
Ok((input, val))
}
}
impl<'i> core::fmt::Debug for CloseResponse<'i> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let mut x = f.debug_struct("CloseResponse");
if let Some(e) = &self.global_signature {
x.field("global_signature", &e);
}
x.finish()
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub(crate) struct EndOfSmlMessage;
impl<'i> SmlParse<'i> for EndOfSmlMessage {
fn parse(input: &'i [u8]) -> ResTy<Self> {
let (input, b) = take_byte(input)?;
if b != 0x00 {
return Err(ParseError::MsgEndMismatch);
}
Ok((input, EndOfSmlMessage))
}
}
#[derive(PartialEq, Eq, Clone)]
pub enum Time {
SecIndex(u32),
}
impl<'i> SmlParseTlf<'i> for Time {
fn check_tlf(tlf: &TypeLengthField) -> bool {
(tlf.ty == Ty::ListOf && tlf.len == 2) || *tlf == TypeLengthField::new(Ty::Unsigned, 4)
}
fn parse_with_tlf(input: &'i [u8], tlf: &TypeLengthField) -> ResTy<'i, Self> {
if *tlf == TypeLengthField::new(Ty::Unsigned, 4) {
let (input, bytes) = take::<4>(input)?;
return Ok((input, Time::SecIndex(u32::from_be_bytes(*bytes))));
}
let (input, tag) = u8::parse(input)?;
match tag {
1 => {
let (input, x) = <u32>::parse(input)?;
Ok((input, Time::SecIndex(x)))
}
_ => Err(ParseError::UnexpectedVariant),
}
}
}
impl ::core::fmt::Debug for Time {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::SecIndex(arg0) => write!(f, "SecIndex({})", arg0),
}
}
}
pub type Signature<'i> = OctetStr<'i>;