1use encoding::Encoding;
2use log::debug;
3use thiserror::Error;
4
5pub mod encoding;
6pub mod length;
7
8#[derive(Debug, PartialEq, Error)]
9pub enum ZVTError {
10 #[error("Incomplete data")]
11 IncompleteData,
12
13 #[error("The following tags are required, but were missing: {0:?}")]
14 MissingRequiredTags(Vec<Tag>),
15
16 #[error("Not implemented")]
17 NonImplemented,
18
19 #[error("Unexpected tag: {0:?}")]
20 WrongTag(Tag),
21
22 #[error("Duplicate tag: {0:?}")]
23 DuplicateTag(Tag),
24
25 #[error("Received an abort {0}")]
26 Aborted(u8),
27}
28
29pub type ZVTResult<T> = ::std::result::Result<T, ZVTError>;
30
31#[derive(Debug, PartialEq, Clone)]
35pub struct Tag(pub u16);
36
37pub trait ZvtCommand {
41 const CLASS: u8;
42 const INSTR: u8;
43}
44
45pub trait NotZvtCommand {}
46
47pub trait ZvtSerializerImpl<
67 L: length::Length = length::Empty,
68 E: encoding::Encoding<Self> = encoding::Default,
69 TE: encoding::Encoding<Tag> = encoding::Default,
70> where
71 Self: Sized,
72{
73 fn serialize_tagged(&self, tag: Option<Tag>) -> Vec<u8> {
74 let mut output = Vec::new();
75 if let Some(tag) = tag {
76 output = TE::encode(&tag);
77 }
78 let mut payload = E::encode(self);
79 let mut length = L::serialize(payload.len());
80 output.append(&mut length);
81 output.append(&mut payload);
82 output
83 }
84
85 fn deserialize_tagged(mut bytes: &[u8], tag: Option<Tag>) -> ZVTResult<(Self, &[u8])> {
86 if let Some(desired_tag) = tag {
87 let actual_tag;
88 (actual_tag, bytes) = TE::decode(bytes)?;
89 if actual_tag != desired_tag {
90 return Err(ZVTError::WrongTag(actual_tag));
91 }
92 debug!(
93 "found tag: 0x{:x}, remaining bytes after tag: {:x?}",
94 actual_tag.0, bytes
95 );
96 }
97 let (length, payload) = L::deserialize(bytes)?;
98 if length > payload.len() {
99 return Err(ZVTError::IncompleteData);
100 }
101 let (data, remainder) = E::decode(&payload[..length])?;
102
103 Ok((data, &payload[length - remainder.len()..]))
104 }
105}
106
107impl<T, L: length::Length, E: encoding::Encoding<T>, TE: encoding::Encoding<Tag>>
117 ZvtSerializerImpl<L, E, TE> for Option<T>
118where
119 T: ZvtSerializerImpl<L, E, TE>,
120{
121 fn serialize_tagged(&self, tag: Option<Tag>) -> Vec<u8> {
122 match self {
124 None => Vec::new(),
125 Some(ref data) => <T as ZvtSerializerImpl<L, E, TE>>::serialize_tagged(data, tag),
126 }
127 }
128
129 fn deserialize_tagged(bytes: &[u8], tag: Option<Tag>) -> ZVTResult<(Self, &[u8])> {
130 match &tag {
133 Some(_) => match <T as ZvtSerializerImpl<L, E, TE>>::deserialize_tagged(bytes, tag) {
134 Err(err) => Err(err),
135 Ok(data) => Ok((Some(data.0), data.1)),
136 },
137 None => match <T as ZvtSerializerImpl<L, E, TE>>::deserialize_tagged(bytes, None) {
138 Err(_) => Ok((None, bytes)),
139 Ok(data) => Ok((Some(data.0), data.1)),
140 },
141 }
142 }
143}
144
145impl<T, L: length::Length, E: encoding::Encoding<T>, TE: encoding::Encoding<Tag>>
160 ZvtSerializerImpl<L, E, TE> for Vec<T>
161where
162 T: ZvtSerializerImpl<L, E, TE>,
163{
164 fn serialize_tagged(&self, tag: Option<Tag>) -> Vec<u8> {
165 self.iter()
166 .flat_map(|item| {
167 <T as ZvtSerializerImpl<L, E, TE>>::serialize_tagged(item, tag.clone())
168 })
169 .collect()
170 }
171
172 fn deserialize_tagged(mut bytes: &[u8], tag: Option<Tag>) -> ZVTResult<(Self, &[u8])> {
173 let mut items = Vec::new();
174
175 while let Ok((item, remainder)) =
176 <T as ZvtSerializerImpl<L, E, TE>>::deserialize_tagged(bytes, tag.clone())
177 {
178 items.push(item);
179 bytes = remainder;
180 }
181
182 Ok((items, bytes))
183 }
184}
185
186pub trait ZvtSerializer: ZvtSerializerImpl
191where
192 Self: Sized,
193 encoding::Default: encoding::Encoding<Self>,
194{
195 fn zvt_serialize(&self) -> Vec<u8> {
196 <Self as ZvtSerializerImpl>::serialize_tagged(self, None)
197 }
198
199 fn zvt_deserialize(bytes: &[u8]) -> ZVTResult<(Self, &[u8])> {
200 <Self as ZvtSerializerImpl>::deserialize_tagged(bytes, None)
201 }
202}
203
204impl<T> ZvtSerializer for T
206where
207 Self: ZvtCommand
208 + ZvtSerializerImpl<length::Adpu, encoding::Default, encoding::BigEndian>
209 + ZvtSerializerImpl,
210 encoding::Default: encoding::Encoding<Self>,
211{
212 fn zvt_serialize(&self) -> Vec<u8> {
213 let tag: Tag = encoding::BigEndian::decode(&[Self::CLASS, Self::INSTR])
215 .unwrap()
216 .0;
217 <Self as ZvtSerializerImpl<length::Adpu, encoding::Default, encoding::BigEndian>>::serialize_tagged(self, Some(tag))
218 }
219
220 fn zvt_deserialize(bytes: &[u8]) -> ZVTResult<(Self, &[u8])> {
221 let tag: Tag = encoding::BigEndian::decode(&[Self::CLASS, Self::INSTR])
222 .unwrap()
223 .0;
224 <Self as ZvtSerializerImpl<length::Adpu, encoding::Default, encoding::BigEndian>>::deserialize_tagged(bytes, Some(tag))
225 }
226}
227
228pub trait ZvtParser
229where
230 Self: Sized,
231{
232 fn zvt_parse(bytes: &[u8]) -> ZVTResult<Self>;
233}