kmip_ttlv/
de.rs

1//! High-level Serde based deserialization of TTLV bytes to Rust data types.
2
3use std::{
4    cell::{RefCell, RefMut},
5    cmp::Ordering,
6    collections::HashMap,
7    io::{Cursor, Read},
8    ops::Deref,
9    rc::Rc,
10    str::FromStr,
11};
12
13use serde::{
14    de::{DeserializeOwned, EnumAccess, MapAccess, SeqAccess, VariantAccess, Visitor},
15    Deserialize, Deserializer,
16};
17
18use crate::traits::AnySyncRead;
19use crate::{
20    error::Error,
21    error::{ErrorKind, ErrorLocation, MalformedTtlvError, Result, SerdeError},
22    types::{
23        self, FieldType, SerializableTtlvType, TtlvBoolean, TtlvDateTime, TtlvEnumeration, TtlvInteger, TtlvLength,
24        TtlvLongInteger, TtlvStateMachine, TtlvStateMachineMode, TtlvTextString,
25    },
26    types::{TtlvBigInteger, TtlvByteString, TtlvTag, TtlvType},
27};
28
29// --- Public interface ------------------------------------------------------------------------------------------------
30
31/// Configuration settings used by the deserializer.
32///
33/// May in future also be used by the serializer.
34#[derive(Debug, Default)]
35pub struct Config {
36    max_bytes: Option<u32>,
37    read_buf: Option<RefCell<Vec<u8>>>,
38}
39
40impl Clone for Config {
41    fn clone(&self) -> Self {
42        Self {
43            max_bytes: self.max_bytes,
44            read_buf: if self.has_buf() {
45                Some(RefCell::new(Vec::new()))
46            } else {
47                None
48            },
49        }
50    }
51}
52
53impl Config {
54    pub fn new() -> Self {
55        Self::default()
56    }
57}
58
59impl Config {
60    /// What, if any, is the configured maximum permitted response size?
61    pub fn max_bytes(&self) -> Option<u32> {
62        self.max_bytes
63    }
64
65    /// Has a persistent read buffer been configured for reading response bytes into?
66    pub fn has_buf(&self) -> bool {
67        self.read_buf.is_some()
68    }
69
70    /// Get mutable access to optional persistent response bytes buffer
71    pub fn read_buf(&self) -> Option<RefMut<Vec<u8>>> {
72        self.read_buf.as_ref().map(|buf| buf.borrow_mut())
73    }
74}
75
76// Builder style interface
77impl Config {
78    /// Specify a maximum number of response bytes to read.
79    ///
80    /// Use this if you are reading data from an untrusted source. If that source then sends a very large response we
81    /// will reject it rather than attempt to read it all and thus avoid possibly running out of memory.
82    pub fn with_max_bytes(self, max_bytes: u32) -> Self {
83        Self {
84            max_bytes: Some(max_bytes),
85            ..self
86        }
87    }
88
89    /// Save the read response bytes into a buffer for use later.
90    ///
91    /// Allocate a persistent buffer that can be used by a reader to store the read response bytes into. This could be
92    /// to avoid allocating a buffer for every response read, or to permit logging or storing or pretty printing of the
93    /// response bytes once they have been read from the source.
94    pub fn with_read_buf(self) -> Self {
95        Self {
96            read_buf: Some(RefCell::new(Vec::new())),
97            ..self
98        }
99    }
100}
101
102/// Read and deserialize bytes from the given slice.
103pub fn from_slice<'de, T>(bytes: &'de [u8]) -> Result<T>
104where
105    T: Deserialize<'de>,
106{
107    let cursor = &mut Cursor::new(bytes);
108    let mut deserializer = TtlvDeserializer::from_slice(cursor);
109    T::deserialize(&mut deserializer)
110}
111
112/// Read and deserialize bytes from the given reader.
113///
114/// Note: Also accepts a mut reference.
115///
116/// Attempting to process a stream whose initial TTL header length value is larger the config max_bytes, if any, will
117/// result in`Error::ResponseSizeExceedsLimit`.
118#[maybe_async::maybe_async]
119pub async fn from_reader<T, R>(mut reader: R, config: &Config) -> Result<T>
120where
121    T: DeserializeOwned,
122    R: AnySyncRead,
123{
124    // When reading from a stream we don't know how many bytes to read until we've read the L of the first TTLV in
125    // the response stream. As the current implementation jumps around in the response bytes while parsing (see
126    // calls to set_position()), and requiring the caller to provider a Seek capable stream would be quite onerous,
127    // and as we're not trying to be super efficient as HSMs are typically quite slow anywa, just read the bytes into a
128    // Vec and then parse it from there. We can't just call read_to_end() because that can cause the response reading to
129    // block if the server doesn't close the connection after writing the response bytes (e.g. PyKMIP behaves this way).
130    // We know from the TTLV specification that the initial TTL bytes must be 8 bytes long (3-byte tag, 1-byte type,
131    // 4-byte length) so we attempt read to this "magic header" from the given stream.
132
133    fn cur_pos(buf_len: u64) -> ErrorLocation {
134        ErrorLocation::from(buf_len)
135    }
136
137    let max_bytes = config.max_bytes();
138
139    // Interior mutability access dance
140    // --------------------------------
141    // The Config object can optionally have its own buffer which we will write the read bytes into. This then allows
142    // the caller to log or save or pretty print those bytes or avoid allocating a new buffer on every read, or
143    // whatever the caller wants to do with them.
144    //
145    // We could take a buffer as an argument but that would complicate the default use case. We could also take a
146    // mutable reference to the Config object but then we'd appear to have the ability to alter the configuration
147    // settings which is not right. So instead we use the interior mutability pattern to get a mutable reference to
148    // just the buffer owned by the Config object, not the entire Config object. However, to write to the Config object
149    // buffer if available or otherwise to a local buffer requires a bit of a dance to get satisfy the Rust compiler
150    // borrow checker.
151    let mut buf_bytes;
152    let mut config_buf = config.read_buf();
153    let mut buf: &mut Vec<u8> = if let Some(ref mut buf) = config_buf {
154        // Use the buffer provided by the Config object.
155        buf
156    } else {
157        // Create and use our own temporary buffer.
158        buf_bytes = Vec::new();
159        &mut buf_bytes
160    };
161
162    // Greedy closure capturing:
163    // -------------------------
164    // Note: In the read_xxx() calls below we take the cursor.position() _before_ the read because otherwise, in Rust
165    // 2018 Edition, the closure captures the cursor causing compilation to fail due to multiple mutable borrows of fhe
166    // cursor. Rust 2021 Edition implements so-called "Disjoint capture in closures" which may eliminate this problem.
167    // See: https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html
168
169    // Read the bytes of the first TTL (3 byte tag, 1 byte type, 4 byte len)
170    buf.resize(8, 0);
171    let response_size;
172    let tag;
173    let r#type;
174    {
175        let mut state = TtlvStateMachine::new(TtlvStateMachineMode::Deserializing);
176        reader.read_exact(buf).await.map_err(|err| pinpoint!(err, cur_pos(0)))?;
177
178        // Extract and verify the first T (tag)
179        let mut cursor = Cursor::new(&mut buf);
180        let buf_len = cursor.position();
181        tag = TtlvDeserializer::read_tag(&mut cursor, Some(&mut state))
182            .map_err(|err| pinpoint!(err, cur_pos(buf_len)))?;
183
184        // Extract and verify the second T (type)
185        let buf_len = cursor.position();
186        r#type = TtlvDeserializer::read_type(&mut cursor, Some(&mut state))
187            .map_err(|err| pinpoint!(err, cur_pos(buf_len), tag))?;
188
189        // Extract and verify the L (value length)
190        let buf_len = cursor.position();
191        let additional_len = TtlvDeserializer::read_length(&mut cursor, Some(&mut state))
192            .map_err(|err| pinpoint!(err, cur_pos(buf_len), tag, r#type))?;
193
194        // ------------------------------------------------------------------------------------------
195        // Now read the value bytes of the first TTLV item (i.e. the rest of the entire TTLV message)
196        // ------------------------------------------------------------------------------------------
197
198        // The number of bytes to allocate is determined by the data being read. It could be a gazillion bytes and we'd
199        // panic trying to allocate it. The caller is therefore advised to define an upper bound if the source cannot be
200        // trusted.
201        let buf_len = cursor.position();
202        response_size = buf_len + (additional_len as u64);
203        if let Some(max_bytes) = max_bytes {
204            if response_size > (max_bytes as u64) {
205                let error = ErrorKind::ResponseSizeExceedsLimit(response_size as usize);
206                let location = ErrorLocation::from(cursor).with_tag(tag).with_type(r#type);
207                return Err(Error::pinpoint(error, location));
208            }
209        }
210    }
211
212    // Warning: this will panic if it fails to allocate the requested amount of memory, at least until try_reserve() is
213    // stabilized!
214    buf.resize(response_size as usize, 0);
215    reader
216        .read_exact(&mut buf[8..])
217        .await
218        .map_err(|err| Error::pinpoint(err, ErrorLocation::from(buf.len()).with_tag(tag).with_type(r#type)))?;
219
220    from_slice(buf)
221}
222
223// --- Private implementation details ----------------------------------------------------------------------------------
224
225// Required for impl Deserializer below to use this type, but I don't really want arbitrary strings leaking out of the
226// deserializer as they could leak sensitive data
227impl serde::de::Error for Error {
228    fn custom<T: std::fmt::Display>(msg: T) -> Self {
229        pinpoint!(SerdeError::Other(msg.to_string()), ErrorLocation::unknown())
230    }
231}
232
233impl<'de: 'c, 'c> From<&mut TtlvDeserializer<'de, 'c>> for ErrorLocation {
234    fn from(de: &mut TtlvDeserializer) -> Self {
235        de.location()
236    }
237}
238
239impl<'de: 'c, 'c> From<&TtlvDeserializer<'de, 'c>> for ErrorLocation {
240    fn from(de: &TtlvDeserializer) -> Self {
241        de.location()
242    }
243}
244
245trait ContextualErrorSupport {
246    fn pos(&self) -> u64;
247}
248
249pub(crate) struct TtlvDeserializer<'de: 'c, 'c> {
250    src: &'c mut Cursor<&'de [u8]>,
251
252    state: Rc<RefCell<TtlvStateMachine>>,
253
254    // for container/group types (map, seq)
255    #[allow(dead_code)]
256    group_start: u64,
257    group_tag: Option<TtlvTag>,
258    group_type: Option<TtlvType>,
259    group_end: Option<u64>,
260    group_fields: &'static [&'static str], // optional field handling: expected fields to compare to actual fields
261    group_item_count: usize,               // optional field handling: index into the group_fields array
262    group_homogenous: bool,                // sequence/map field handling: are all items in the group of the same type?
263
264    // for the current field being parsed
265    item_start: u64, // optional field handling: point to return to if field is missing
266    item_tag: Option<TtlvTag>,
267    item_type: Option<TtlvType>,
268    item_unexpected: bool, // optional field handling: is this tag wrong for the expected field (and thus is missing?)
269    item_identifier: Option<String>,
270
271    // lookup maps
272    tag_value_store: Rc<RefCell<HashMap<TtlvTag, String>>>,
273    matcher_rule_handlers: [(&'static str, MatcherRuleHandlerFn<'de, 'c>); 3],
274
275    // diagnostic support
276    tag_path: Rc<RefCell<Vec<TtlvTag>>>,
277}
278
279type MatcherRuleHandlerFn<'de, 'c> =
280    fn(&TtlvDeserializer<'de, 'c>, &str, &str) -> std::result::Result<bool, types::Error>;
281
282impl<'de: 'c, 'c> TtlvDeserializer<'de, 'c> {
283    // This is not a global read-only static array as they do not support lifetime specification which is required
284    // by the Self::fn_name references which is in turn required because the handler functions can use arbitrary data
285    // from the current instance of the deserializer. One could argue that the set of matcher fns is fixed and thus we
286    // can concretely specify everything in advance, but I'm not convinced that's really more readable.
287    fn init_matcher_rule_handlers() -> [(&'static str, MatcherRuleHandlerFn<'de, 'c>); 3] {
288        [
289            ("==", Self::handle_matcher_rule_eq),
290            (">=", Self::handle_matcher_rule_ge),
291            ("in", Self::handle_matcher_rule_in),
292        ]
293    }
294
295    pub fn from_slice(cursor: &'c mut Cursor<&'de [u8]>) -> Self {
296        Self {
297            src: cursor,
298            state: Rc::new(RefCell::new(TtlvStateMachine::new(TtlvStateMachineMode::Deserializing))),
299            group_start: 0,
300            group_tag: None,
301            group_type: None,
302            group_end: None,
303            group_fields: &[],
304            group_item_count: 0,
305            group_homogenous: false,
306            item_start: 0,
307            item_tag: None,
308            item_type: None,
309            item_unexpected: false,
310            item_identifier: None,
311            tag_value_store: Rc::new(RefCell::new(HashMap::new())),
312            matcher_rule_handlers: Self::init_matcher_rule_handlers(),
313            tag_path: Rc::new(RefCell::new(Vec::new())),
314        }
315    }
316
317    #[allow(clippy::too_many_arguments)]
318    fn from_cursor(
319        src: &'c mut Cursor<&'de [u8]>,
320        state: Rc<RefCell<TtlvStateMachine>>,
321        group_tag: TtlvTag,
322        group_type: TtlvType,
323        group_end: u64,
324        group_fields: &'static [&'static str],
325        group_homogenous: bool, // are all items in the group the same tag and type?
326        unit_enum_store: Rc<RefCell<HashMap<TtlvTag, String>>>,
327        tag_path: Rc<RefCell<Vec<TtlvTag>>>,
328    ) -> Self {
329        let group_start = src.position();
330        let group_tag = Some(group_tag);
331        let group_type = Some(group_type);
332        let group_end = Some(group_end);
333
334        Self {
335            src,
336            state,
337            group_start,
338            group_tag,
339            group_type,
340            group_end,
341            group_fields,
342            group_item_count: 0,
343            group_homogenous,
344            item_start: group_start,
345            item_tag: None,
346            item_type: None,
347            item_unexpected: false,
348            item_identifier: None,
349            tag_value_store: unit_enum_store,
350            matcher_rule_handlers: Self::init_matcher_rule_handlers(),
351            tag_path,
352        }
353    }
354
355    /// Read a 3-byte TTLV tag into an [TtlvTag].
356    ///
357    /// This function is not normally intended to be used directly. Instead use [from_slice] or [from_reader].
358    ///
359    /// Note: Also accepts a mut reference.
360    ///
361    /// # Errors
362    ///
363    /// If this function is unable to read 3 bytes from the given reader an [Error::IoError] will be returned.
364    ///
365    /// If the state machine is not in the expected state then [Error::UnexpectedTtlvField] will be returned.
366    pub(crate) fn read_tag<R>(
367        mut src: R,
368        state: Option<&mut TtlvStateMachine>,
369    ) -> std::result::Result<TtlvTag, types::Error>
370    where
371        R: Read,
372    {
373        if let Some(state) = state {
374            state.advance(FieldType::Tag)?;
375        }
376        TtlvTag::read(&mut src)
377    }
378
379    /// Read a 1-byte TTLV type into an [ItemType]
380    ///
381    /// This function is not normally intended to be used directly. Instead use [from_slice] or [from_reader].
382    ///
383    /// Note: Also accepts a mut reference.
384    ///
385    /// # Errors
386    ///
387    /// If this function is unable to read 1 byte from the given reader an [Error::IoError] will be returned.
388    ///
389    /// If the read byte is not a valid value according to the KMIP 1.0 TTLV specification or is a type which
390    /// we do not yet support an error will be returned.
391    ///
392    /// If the state machine is not in the expected state then [Error::UnexpectedTtlvField] will be returned.
393    pub(crate) fn read_type<R>(
394        mut src: R,
395        state: Option<&mut TtlvStateMachine>,
396    ) -> std::result::Result<TtlvType, types::Error>
397    where
398        R: Read,
399    {
400        if let Some(state) = state {
401            state.advance(FieldType::Type)?;
402        }
403        TtlvType::read(&mut src)
404    }
405
406    /// Read a 4-byte TTLV length into a u32.
407    ///
408    /// This function is not normally intended to be used directly. Instead use [from_slice] or [from_reader].
409    ///
410    /// Note: Also accepts a mut reference.
411    ///
412    /// # Errors
413    ///
414    /// If this function is unable to read 4 bytes from the given reader an [Error::IoError] will be returned.
415    ///
416    /// If the state machine is not in the expected state then [Error::UnexpectedTtlvField] will be returned.
417    pub(crate) fn read_length<R>(
418        mut src: R,
419        state: Option<&mut TtlvStateMachine>,
420    ) -> std::result::Result<u32, types::Error>
421    where
422        R: Read,
423    {
424        if let Some(state) = state {
425            state.advance(FieldType::Length)?;
426        }
427        TtlvLength::read(&mut src).map(|len| *len)
428    }
429
430    /// Read the next TTLV tag and type header and prepare for full deserialization.
431    ///
432    /// Returns Ok(true) if there is data available, Ok(false) if the end of the current group (TTLV sequence or
433    /// structure) has been reached or an I/O error or `MalformedTtlvError` (e.g. if the tag or type are invalid or if
434    /// the read cursor is past the last byte of the group).
435    fn read_item_key(&mut self, use_group_fields: bool) -> Result<bool> {
436        if let Some(group_end) = self.group_end {
437            match self.pos().cmp(&group_end) {
438                Ordering::Less => {
439                    // More bytes to read
440                }
441                Ordering::Equal => {
442                    // End of group reached
443                    return Ok(false);
444                }
445                Ordering::Greater => {
446                    // Error: Read cursor is beyond the end of the current TTLV group
447                    let error = MalformedTtlvError::overflow(group_end);
448                    let location = self.location();
449                    return Err(Error::pinpoint(error, location));
450                }
451            }
452        } else {
453            unreachable!()
454        }
455
456        if use_group_fields {
457            self.item_start = self.group_start;
458            self.item_tag = self.group_tag;
459            self.item_type = self.group_type;
460        } else {
461            self.item_start = self.pos() as u64;
462            self.item_tag = None;
463            self.item_type = None;
464
465            let loc = self.location(); // See the note above about working around greedy closure capturing
466            self.item_tag = Some(
467                Self::read_tag(&mut self.src, Some(&mut self.state.borrow_mut()))
468                    .map_err(|err| Error::pinpoint(err, loc))?,
469            );
470
471            let loc = self.location(); // See the note above about working around greedy closure capturing
472            self.item_type = Some(
473                Self::read_type(&mut self.src, Some(&mut self.state.borrow_mut()))
474                    .map_err(|err| Error::pinpoint(err, loc))?,
475            );
476        }
477
478        // As we are invoked for every field that Serde derive found on the target Rust struct we need to handle the
479        // not just the case where the expected tag is present in the byte stream in the expected position in the
480        // sequence, but also:
481        //
482        //   - `Option` fields: these represent fields that may optionally exist in the byte stream, i.e. for a Rust
483        //     struct field with `#[serde(rename = "0x123456")]` is the next item tag in the byte stream 0x123456 or
484        //     something else (because 0x123456 is correctly missing from the byte stream)? These should be
485        //     deserialized as `Some` if present, `None` otherwise.
486        //
487        //   - Missing fields; tags that exist in the byte stream but do not have a corresponding field in the Rust
488        //     struct. These should be ignored unless `#[serde(deny_unknown_fields)]` has been used.
489        //
490        //   - Extra fields: tags that exist in the Rust struct but not in the byte stream. These represent missing
491        //     but required data which the absence of which should cause deserialization to fail.
492        //
493        // Serde derive expects that we announce the name of the field that we have encountered in the byte stream,
494        // i.e. that `fn deserialize_identifier()` will invoke `visitor.visit_str()` with the *Rust* field name. Due to
495        // our abuse of `#[serde(rename)]` we can't just announce the TTLV tag hex representation as the *Rust* field
496        // name, the *Rust* field name may be something special like "if 0x123456 in ...". Serde derive will only
497        // accept our deserialized value for the field if we announce the exact same name as the field was assigned in
498        // the Rust struct via `#[serde(rename)])`.
499        //
500        // To know which Rust name to announce as the field identifier we rely on the fact that the KMIP TTLV
501        // specification states that "All fields SHALL appear in the order specified" and that Serde derive earlier
502        // gave us the set of field names in the group when processing of the group stated. We keep track of how many
503        // items we have seen in the group and thus expect that for item N we can assume that Serde derive expects us
504        // to announce the Nth group field name.
505        //
506        // We compare the Nth field name to the tag of the next TTLV item. If N >= M, where N is zero-based and M is
507        // the number of fields that Serde derive communicated to us at the start of the group, we announce the TTLV
508        // tag in hex form as the field name so that something useful appears in the Serde error message if any. By
509        // default Serde will ignore the field value by invoking `fn deserialized_ignored_any()` and we will skip over
510        // the bytes of the TTLV item in the stream as if it were not there. If however `#[serde(deny_unknown_fields)]`
511        // is in use this scenario causes Serde derive to abort deserialization with an error.
512        //
513        // If the read tag doesn't match the expected tag, we record that the item is unexpected and continue. If the
514        // field in the Rust struct is an `Option` Serde derive will then invoke `fn deserialize_option()` at which
515        // point we detect the recorded unexpected flag and return `None` (because there was no item for that tag at
516        // this point (which is the correct position in the Rust struct/TTLV Structure sequence for the item) in the
517        // byte stream.
518
519        self.group_item_count += 1;
520
521        self.item_unexpected = if self.group_fields.is_empty() {
522            // We have no idea which field is expected so this field cannot be unexpected, but we also cannot set the
523            // item identifier to announce for this field (though we might establish an identifier subsequently, e.g.
524            // in the case of selecting the appropriate Rust enum variant).
525            false
526        } else {
527            let field_index = self.group_item_count - 1;
528            let actual_tag_str = &self.item_tag.unwrap().to_string();
529            let expected_tag_str = self
530                .group_fields
531                .get(field_index)
532                .map_or_else(|| actual_tag_str.clone(), |v| v.to_string());
533            self.item_identifier = Some(expected_tag_str.clone());
534            actual_tag_str != &expected_tag_str
535        };
536
537        Ok(true)
538    }
539
540    fn get_start_tag_type(&mut self) -> Result<(u64, TtlvTag, TtlvType)> {
541        let (group_start, group_tag, group_type) = if self.pos() == 0 {
542            // When invoked by Serde via from_slice() there is no prior call to next_key_seed() that reads the tag and
543            // type as we are not visiting a map at that point. Thus we need to read the opening tag and type here.
544            let group_start = self.src.position();
545
546            let loc = self.location(); // See the note above about working around greedy closure capturing
547            let group_tag =
548                Self::read_tag(&mut self.src, Some(&mut self.state.borrow_mut())).map_err(|err| pinpoint!(err, loc))?;
549            self.item_tag = Some(group_tag);
550
551            let loc = self.location(); // See the note above about working around greedy closure capturing
552            let group_type = Self::read_type(&mut self.src, Some(&mut self.state.borrow_mut()))
553                .map_err(|err| pinpoint!(err, loc))?;
554            self.item_type = Some(group_type);
555
556            (group_start, group_tag, group_type)
557        } else {
558            // When invoked while visiting a map the opening tag and type of the struct header will have already been
559            // read by next_key_seed() so we don't need to read them here.
560            (self.src.position() - 4, self.item_tag.unwrap(), self.item_type.unwrap())
561        };
562        Ok((group_start, group_tag, group_type))
563    }
564
565    fn prepare_to_descend(&mut self, name: &'static str) -> Result<(u64, TtlvTag, TtlvType, u64)> {
566        let loc = self.location(); // See the note above about working around greedy closure capturing
567        let wanted_tag = TtlvTag::from_str(name).map_err(|err| pinpoint!(err, loc))?;
568
569        let (group_start, group_tag, group_type) = self.get_start_tag_type()?;
570
571        if group_tag != wanted_tag {
572            return Err(pinpoint!(
573                SerdeError::UnexpectedTag {
574                    expected: wanted_tag,
575                    actual: group_tag
576                },
577                self
578            ));
579        }
580
581        if group_type != TtlvType::Structure {
582            return Err(pinpoint!(
583                MalformedTtlvError::UnexpectedType {
584                    expected: TtlvType::Structure,
585                    actual: group_type
586                },
587                self
588            ));
589        }
590
591        let loc = self.location(); // See the note above about working around greedy closure capturing
592        let group_len =
593            Self::read_length(&mut self.src, Some(&mut self.state.borrow_mut())).map_err(|err| pinpoint!(err, loc))?;
594        let group_end = self.pos() + (group_len as u64);
595        Ok((group_start, group_tag, group_type, group_end))
596    }
597
598    fn is_variant_applicable(&self, variant: &'static str) -> Result<bool> {
599        // str::split_once() wasn't stablized until Rust 1.52.0 but as we want to be usable by Krill, and Krill
600        // supported Rust >= 1.49.0 at the time of writing, we use our own split_once() implementation.
601        pub fn split_once<'a>(value: &'a str, delimiter: &str) -> Option<(&'a str, &'a str)> {
602            value
603                .find(delimiter)
604                .map(|idx| (&value[..idx], &value[idx + delimiter.len()..]))
605        }
606
607        if let Some(rule) = variant.strip_prefix("if ") {
608            for (op, handler_fn) in &self.matcher_rule_handlers {
609                if let Some((wanted_tag, wanted_val)) = split_once(rule, op) {
610                    return handler_fn(self, wanted_tag.trim(), wanted_val.trim()).map_err(|err| pinpoint!(err, self));
611                }
612            }
613
614            return Err(pinpoint!(SerdeError::InvalidVariantMatcherSyntax(variant.into()), self));
615        }
616
617        Ok(false)
618    }
619
620    fn handle_matcher_rule_eq(&self, wanted_tag: &str, wanted_val: &str) -> std::result::Result<bool, types::Error> {
621        if wanted_tag == "type" {
622            // See if wanted_val is a literal string that matches the TTLV type we are currently deserializing
623            // TODO: Add BigInteger and Interval when supported
624            if matches!(
625                (wanted_val, self.item_type.unwrap()),
626                ("Structure", TtlvType::Structure)
627                    | ("Integer", TtlvType::Integer)
628                    | ("LongInteger", TtlvType::LongInteger)
629                    | ("Enumeration", TtlvType::Enumeration)
630                    | ("Boolean", TtlvType::Boolean)
631                    | ("TextString", TtlvType::TextString)
632                    | ("ByteString", TtlvType::ByteString)
633                    | ("DateTime", TtlvType::DateTime)
634            ) {
635                return Ok(true);
636            }
637        } else if let Ok(wanted_tag) = TtlvTag::from_str(wanted_tag) {
638            if let Some(seen_enum_val) = self.lookup_tag_value(wanted_tag) {
639                if seen_enum_val == wanted_val {
640                    return Ok(true);
641                }
642            }
643        }
644
645        Ok(false)
646    }
647
648    fn handle_matcher_rule_ge(&self, wanted_tag: &str, wanted_val: &str) -> std::result::Result<bool, types::Error> {
649        if let Some(seen_enum_val) = self.tag_value_store.borrow().get(&TtlvTag::from_str(wanted_tag)?) {
650            if TtlvTag::from_str(seen_enum_val)?.deref() >= TtlvTag::from_str(wanted_val)?.deref() {
651                return Ok(true);
652            }
653        }
654
655        Ok(false)
656    }
657
658    fn handle_matcher_rule_in(&self, wanted_tag: &str, wanted_val: &str) -> std::result::Result<bool, types::Error> {
659        let wanted_values = wanted_val.strip_prefix('[').and_then(|v| v.strip_suffix(']'));
660        if let Some(wanted_values) = wanted_values {
661            if let Some(seen_enum_val) = self.tag_value_store.borrow().get(&TtlvTag::from_str(wanted_tag)?) {
662                for wanted_value in wanted_values.split(',') {
663                    if *seen_enum_val == wanted_value.trim() {
664                        return Ok(true);
665                    }
666                }
667            }
668        }
669
670        Ok(false)
671    }
672
673    fn location(&self) -> ErrorLocation {
674        let mut loc = ErrorLocation::at(self.src.position().into()).with_parent_tags(&self.tag_path.borrow());
675
676        if let Some(tag) = self.item_tag {
677            loc = loc.with_tag(tag);
678        }
679
680        if let Some(r#type) = self.item_type {
681            loc = loc.with_type(r#type);
682        }
683
684        loc
685    }
686
687    fn remember_tag_value<T>(&self, tag: TtlvTag, value: T)
688    where
689        String: From<T>,
690    {
691        self.tag_value_store.borrow_mut().insert(tag, value.into());
692    }
693
694    fn lookup_tag_value(&self, tag: TtlvTag) -> Option<String> {
695        self.tag_value_store.borrow().get(&tag).cloned()
696    }
697
698    fn seek_forward(&mut self, num_bytes_to_skip: u32) -> Result<u64> {
699        use std::io::Seek;
700        self.src
701            .seek(std::io::SeekFrom::Current(num_bytes_to_skip as i64))
702            .map_err(|err| pinpoint!(err, self))
703    }
704}
705
706// TODO: remove this
707impl<'de: 'c, 'c> ContextualErrorSupport for TtlvDeserializer<'de, 'c> {
708    fn pos(&self) -> u64 {
709        self.src.position()
710    }
711}
712
713macro_rules! unsupported_type {
714    ($deserialize:ident, $type:ident) => {
715        fn $deserialize<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
716            Err(pinpoint!(
717                SerdeError::UnsupportedRustType(stringify!($type)),
718                self
719            ))
720        }
721    };
722}
723
724impl<'de: 'c, 'c> Deserializer<'de> for &mut TtlvDeserializer<'de, 'c> {
725    type Error = Error;
726
727    /// Deserialize the bytes at the current cursor position to a Rust structure.
728    ///
729    /// The use of a Rust structure by the caller is assumed to signify that the TTLV item should be of TTLV type
730    /// "Structure". E.g. given something like:
731    ///
732    /// ```ignore
733    /// #[derive(Deserialize)]
734    /// #[serde(rename = "0x012345")]
735    /// struct MyStruct {
736    ///    a: i32,
737    ///    b: MyOtherStruct,
738    /// }
739    /// ```
740    ///
741    /// This function will be invoked with the `name` parameter set to `0x012345` (or `MyStruct` if `rename` were not
742    /// used), with the `fields` parameter set to `['a', 'b']`. Serde requires that we delegate to either `visit_map()`
743    /// or `visit_seq()`. These delegates are responsible for issuing key/value pairs that correspond to the struct
744    /// fields (e.g. `a` and `b` in the example above) being processed by Serde.
745    ///
746    /// For keys serde invokes `deserialize_identifier()` to parse out the field name from the byte stream and pass it
747    /// to `visit_str()`.
748    ///
749    /// For values serde invokes the corresponding trait function in this impl, e.g. `deserialize_i32()`, to
750    /// parse out the TTLV value and pass it to the corresponding visit function such as `visit_i32()`. For
751    /// complex types such as a struct or vec the `deserialize_struct` (i.e. recursion) or `deserialize_seq` will be
752    /// invoked.
753    ///
754    /// We have to be careful to handle correctly the fact that the Rust structure fields are "children" in the TTLV
755    /// byte stream of a TTLV structure, e.g. for the example above the byte stream might contain TTLV bytes like so:
756    ///
757    /// ```text
758    ///   TTLVVVVVVVVVVVVVVVVVV <- the TTLV representation of 'MyStruct'
759    ///      TTLVVTTLVVVVVVVVVV <- the TTLV representation of 'a' and 'b' within 'MyStruct'
760    /// ```
761    ///
762    /// Furthermore, field order in TTLV matters. We remember the given fields and if we encounter a field other than
763    /// the one that we expect we flag it as unexpected. We can't immediately reject it because it could be that the
764    /// caller wrapped the type to deserialize to in a Rust `Option` indicating that the TTLV item is optional. If when
765    /// Serde asks us to process the value we will raise an error if we are not asked to process an `Option`.
766    fn deserialize_struct<V>(self, name: &'static str, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
767    where
768        V: Visitor<'de>,
769    {
770        let (_, group_tag, group_type, group_end) = self.prepare_to_descend(name)?;
771
772        let mut struct_cursor = self.src.clone();
773
774        self.tag_path.borrow_mut().push(group_tag);
775
776        let descendent_parser = TtlvDeserializer::from_cursor(
777            &mut struct_cursor,
778            self.state.clone(),
779            group_tag,
780            group_type,
781            group_end,
782            fields,
783            false, // struct member fields can have different tags and types
784            self.tag_value_store.clone(),
785            self.tag_path.clone(),
786        );
787
788        let r = visitor.visit_map(descendent_parser); // jumps to impl MapAccess below
789
790        // The descendant parser cursor advanced but ours did not. Skip the tag that we just read.
791        self.src.set_position(struct_cursor.position());
792
793        match r {
794            Ok(_) => {
795                self.tag_path.borrow_mut().pop();
796                r
797            }
798            Err(err) => {
799                // Errors can be raised directly by Serde Derive, e.g. SerdeError::Other("missing field"), which
800                // necessarily have ErrorLocation::is_unknown() as Serde Derive is not aware of our ErrorLocation type.
801                // When that happens, this is the first opportunity after calling `visitor.visit_map()` that we have to
802                // add the missing location data. However, if the error _was_ raised by our code and not by Serde
803                // Derive it probably already has location details. Therefore we "merge" the current location into the
804                // error so that only missing details are added if needed as the existing location details may more
805                // point more accurately to the source of the problem than we are able to indicate here (we don't know
806                // where in the `visit_map()` process the issue occured, on which field and at which byte, we just use
807                // the current cursor position and hope that is good enough).
808                let (kind, loc) = err.into_inner();
809                let new_loc = loc.merge(self.location());
810                Err(Error::new(kind, new_loc))
811            }
812        }
813    }
814
815    /// Deserialize the bytes at the current cursor position to a Rust struct with a single field.
816    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
817    where
818        V: Visitor<'de>,
819    {
820        visitor.visit_newtype_struct(self) // jumps to to the appropriate deserializer fn such as deserialize_string()
821    }
822
823    /// Deserialize the bytes at the current cursor position to a Rust vector.
824    ///
825    /// The use of a Rust vector by the caller is assumed to signify that the next items in the TTLV byte stream will
826    /// represent an instance of "MAY be repeated" in the KMIP 1.0 spec. E.g. for [section 4.24 Query of the KMIP 1.0 spec](https://docs.oasis-open.org/kmip/spec/v1.0/os/kmip-spec-1.0-os.html#_Toc262581232)
827    /// for the Query operation response, one could represent the response like so:
828    ///
829    /// ```ignore
830    /// struct QueryResponsePayload {     // OBJECT       REQUIRED
831    ///    operations: Vec<Operation>,    // Operation    No, MAY be repeated
832    ///    object_types: Vec<ObjectType>, // Object Type  No, MAY be repeated
833    ///    ...
834    /// }
835    /// ```
836    ///
837    /// _(the inline comments quote the relevant parts of the KMIP 1.0 spec)_
838    ///
839    /// The KMIP 1.0 spec does not define the terminating conditions for a field that "MAY be repeated. This
840    /// deserializer assumes that the sequence is limited by the L_ength of the TTLV item that contains it and that to
841    /// be considered part of a "MAY be repeated" sequence the TTLV item must have the same tag and type as the previous
842    /// items. Otherwise two adjacent "MAY be repeated" sequences within the same parent TTLV "Structure" would not have
843    /// a clear boundary indicating when one sequence ends and the other starts. For example, checking the tag and type
844    /// are needed to know whether the next TTLV item in the QueryResponsePayload example above is another item in the
845    /// operations vector or is the first item in the object_types vector.
846    ///
847    /// When deserializing a structure the initial TTL is a sort of header for the structure, with the structure field
848    /// values following the header as individual TTLV Items. When deserializing a sequence however the initial TTL is
849    /// not separate to but rather belongs to the first item in the sequence.
850    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
851    where
852        V: Visitor<'de>,
853    {
854        let seq_tag = self.item_tag.unwrap();
855        let seq_type = self.item_type.unwrap();
856        let seq_end = self.group_end.unwrap();
857
858        let mut seq_cursor = self.src.clone();
859
860        let descendent_parser = TtlvDeserializer::from_cursor(
861            &mut seq_cursor,
862            self.state.clone(),
863            seq_tag,
864            seq_type,
865            seq_end,
866            &[],
867            true, // sequence fields must all have the same tag and type
868            self.tag_value_store.clone(),
869            self.tag_path.clone(),
870        );
871
872        let r = visitor.visit_seq(descendent_parser); // jumps to impl SeqAccess below
873
874        // The descendant parser cursor advanced but ours did not. Skip the tag that we just read.
875        self.src.set_position(seq_cursor.position());
876
877        r
878    }
879
880    /// Deserialize the bytes at the current cursor position to a Rust Option.
881    ///
882    /// The TTLV format has no explicit support for optional items, though a client and server may agree that it is okay
883    /// for a particular point in the TTLV byte stream to optionally contain a particular TTLV item. For example the
884    /// KMIP 1.0 spec labels some response fields as NOT required i.e. optional. To handle such cases the caller can use
885    /// the Rust Option type in the datatype being deserialized into. As TTLV has no explicit mechanism to indicate a
886    /// NULL or missing value, the caller MUST treat missing fields that deserialize to an `Option` as `None`. For
887    /// example:
888    ///
889    /// ```ignore
890    /// #[derive(Deserialize)]
891    /// #[serde(rename = "0x42000F")]
892    /// pub struct BatchItem {
893    ///     #[serde(default)]
894    ///     pub operation: Option<Operation>,
895    ///     ...
896    /// }
897    /// ```
898    ///
899    /// Here we see a KMIP BatchItem response structure with an optional field and the use of `#[serde(default)]` to set
900    /// the member field to `None` if the corresponding TTLV item is not found while deserializing.
901    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
902    where
903        V: Visitor<'de>,
904    {
905        // The tag and type have already been read, now we are handling the value. How can we know that this item is
906        // NOT the one that was intended to fill the Option and thus the item is missing and the Option should be
907        // populated with None. This can happen e.g. in the case of a KMIP response the response batch item structure
908        // 0x42000F has several optional member fields including the operation code field 0x42005C. The operation code
909        // field is only required to be present in the response if it was present in the request. The order of fields
910        // in a KMIP structure is also required to match that of the spec and the operation code field is the first
911        // item in the response batch item structure.
912        //
913        // Thus if we define a Rust struct for the response batch item TTLV structure the first member must be an
914        // optional operation code, but the first batch item structure member field present in the TTLV response might
915        // be another response batch item field such as result status 0x42007F. We handle this by detecting the
916        // mismatch between Rust field name (i.e. TTLV tag) and the actual tag code found in the TTLV bytes. If they do
917        // not match and the Rust field was of type Option then we respond as if the field value was read and the
918        // Option should be set to None, but we reset the read cursor in the TTLV byte stream so that we will read this
919        // "wrong" tag again as it should match one of the as yet unprocessed member fields in the Rust struct.
920        //
921        // Finally we have to reset the state machine as we just read a tag and type and the next TTLV fields should be
922        // the length and value, but we are resetting the read cursor to point at the tag again.
923
924        // Is this the field we expected at this point?
925        if self.item_unexpected {
926            // This isn't the item that the caller expected but they indicated that the expected item was optional.
927            // Report back that the optional item was not found and rewind the read cursor so that we will visit this
928            // TTLV tag again.
929            self.src.set_position(self.item_start);
930            // Reset the state machine to expect a tag as it's currently expecting a value but should expect a tag.
931            self.state.borrow_mut().reset();
932            visitor.visit_none()
933        } else {
934            visitor.visit_some(self)
935        }
936    }
937
938    /// Deserialize the bytes at the current cursor position to a Rust unit-like enum variant or struct enum variant.
939    ///
940    /// # Unit-like enum variants
941    ///
942    /// Rust enum variants can be unit-like or can have data attached to them. The unit-like form should be used when
943    /// the TTLV bytes being deserialized are of type "Enumeration". Serde will use the deserialized unsigned 32-bit
944    /// value to select a variant with matching name. By using the serde-derive rename feature we can associate each
945    /// enum variant with a single TTLV "Enumeration" value. For example one could define the first few values of the
946    /// KMIP "Operation" Enumeration like so:
947    ///
948    /// ```ignore
949    /// #[derive(Deserialize, Serialize, Display)]
950    /// #[serde(rename = "0x42005C")]
951    /// #[non_exhaustive]
952    /// pub enum Operation {
953    ///     #[serde(rename = "0x00000001")]
954    ///     Create,
955    ///
956    ///     #[serde(rename = "0x00000002")]
957    ///     CreateKeyPair,
958    ///
959    ///     #[serde(rename = "0x00000003")]
960    ///     Register,
961    /// ```
962    ///
963    /// These enum variants are referred to as unit-like as they have no associated data, i.e. the variants have the
964    /// form `Create` rather than `Create(...some associated data...)`.
965    ///
966    /// The TTLV byte sequence `42005C05000000040000000200000000` will be deserialized as tag `0x42005C`, type 0x05
967    /// (Enumeration), value length 4 (bytes) and a 4-byte 0x00000002 value with 4 bytes of padding. Serde will be
968    /// notified that the callers identifier with name "0x00000002" should have the value `Operation::CreateKeyPair`.
969    ///
970    /// # Struct enum variants
971    ///
972    /// By using an enum with struct variants the caller signals to the deserializer that it expects the TTLV byte
973    /// stream to contain a TTLV "Structure" item that can be deserialized into one of the variant structs, but which
974    /// one? For this to work we must also give the deserializer a way of determining from the data deserialized so far
975    /// which of the variants is represented by the TTLV byte stream. We do this by using a serde "name" with a special
976    /// syntax of the form `if A==B`.
977    ///
978    /// Let's see this in action using the variable KMIP response payload structure layout as an example where the
979    /// payload structure to deserialize is indicated by the KMIP Operation enum value that appears earlier in the TTLV
980    /// byte stream:
981    ///
982    /// First we define a struct that contains the variable payload as a member field:
983    ///
984    /// ```ignore
985    /// #[derive(Deserialize)]
986    /// #[serde(rename = "0x42000F")]
987    /// pub struct BatchItem {
988    ///     pub operation: Option<Operation>,
989    ///     pub payload: Option<ResponsePayload>,
990    /// }
991    /// ```
992    ///
993    /// Then we define the variable payload type as an enum whose variants have different Rust structures attached to
994    /// them. We also signal to the deserializer how each variant is selected by some other value in the TTLV byte
995    /// stream:
996    ///
997    /// ```ignore
998    /// #[derive(Deserialize)]
999    /// #[serde(rename = "0x42007C")]
1000    /// #[non_exhaustive]
1001    /// pub enum ResponsePayload {
1002    ///     #[serde(rename = "if 0x42005C==0x00000001")]
1003    ///     Create(CreateResponsePayload),
1004    ///
1005    ///     #[serde(rename = "if 0x42005C==0x00000002")]
1006    ///     CreateKeyPair(CreateKeyPairResponsePayload),
1007    ///
1008    ///     #[serde(rename = "if 0x42005C==0x00000003")]
1009    ///     Register(RegisterResponsePayload),
1010    /// }
1011    /// ```
1012    ///
1013    /// Where `CreateResponsePayload`, `CreateKeyPairResponsePayload` and `RegisterResponsePayload` are Rust structs
1014    /// defined elsewhere.
1015    ///
1016    /// The special name syntax `if A==B` is used here to select the correct variant by matching against the value of
1017    /// another tag, "Operation" in this case, seen earlier in the TTLV byte stream. A TTLV byte sequence of the form
1018    /// `42000F01LLLLLLLL42005C0500000004000000020000000042007C01LLLLLLLLV...` would be deserialized as operation code
1019    /// 0x00000002 indicating that the payload is of type `CreateKeyPairResponsePayload`.
1020    ///
1021    /// The if syntax currently only supports matching against the value of earlier seen enum or string TTLV items that
1022    /// are looked up by their tag.
1023    fn deserialize_enum<V>(self, name: &'static str, variants: &'static [&'static str], visitor: V) -> Result<V::Value>
1024    where
1025        V: Visitor<'de>,
1026    {
1027        // We don't know which type of enum the caller is deserializing into nor without guidance do we even know which
1028        // variant to announce to Serde that we are populating. We assume that the caller knows whether to expect a
1029        // structure or a single integer value in the TTLV byte stream at this point and that they therefore correctly
1030        // specified a tuple/tuple-struct enum variant or a unit-like variant as the datatype being deserialized into.
1031        //
1032        // We can only do two things:
1033        //   1. Deserialize the type of TTLV item that we find at this point in the byte stream.
1034        //
1035        //   2. Announce to serde either the TTLV tag as the variant name, or if the enum name is in the special form
1036        //      "if A==B" attempt to see if the value of previously seen tag A is B and if so we then announce the
1037        //      "if A==B" variant name as the chosen variant.
1038        //
1039        // When matching against previously seen tag values the match we find is used to tell Serde which enum variant
1040        // to deserialie into. This is the only case where we support an enum within an enum in the Rust code structure,
1041        // as TTLV doesn't support such nesting of enum values, that is we match against the name (or rename) of the
1042        // variant in an outer enum but the TTLV enum value that we read is used to select the variant of an inner enum.
1043        //
1044        // The concrete KMIP use case for such nested enums is when the response includes an Attribute Value whose tag
1045        // cannot tell us which Rust enum variant to deserialize into as it is always the same (0x42000B) so instead we
1046        // want to use the Attribute Name tag (0x42000A) string value seen earlier to select the Rust variant to
1047        // deserialize into, but that variant is itself an enum (e.g. AttributeValue::State(State)) and the actual TTLV
1048        // enum value read selects the variant of this "inner" State enum that will be deserialized into (e.g.
1049        // State::PreActive).
1050
1051        self.item_identifier = None;
1052
1053        // Check each enum variant name to see if it is of the form "if enum_tag==enum_val" and if so extract
1054        // enum_tag and enum_value:
1055        for v in variants {
1056            if self.is_variant_applicable(v)? {
1057                self.item_identifier = Some(v.to_string());
1058                break;
1059            }
1060        }
1061
1062        // 1: Deserialize according to the TTLV item type:
1063        match self.item_type {
1064            Some(TtlvType::Enumeration) | Some(TtlvType::Integer) => {
1065                // 2: Read a TTLV enumeration from the byte stream and announce the read value as the enum variant name.
1066                //    If we are selecting an enum variant based on a special "if" string then item_identifier will be
1067                //    Some(xxx) where xxx will NOT match the TTLV value that is waiting to be read, instead that will
1068                //    match an inner enum variant so we read the TTLV value when we visit this function again deeper in
1069                //    the call hierarchy. This enables handling of cases such as `AttributeName` string field that
1070                //    indicates the enum variant represented by the `AttributeValue`.
1071                if self.item_identifier.is_none() {
1072                    let loc = self.location(); // See the note above about working around greedy closure capturing
1073                    self.state
1074                        .borrow_mut()
1075                        .advance(FieldType::LengthAndValue)
1076                        .map_err(|err| pinpoint!(err, loc.clone()))?;
1077                    let enum_val = TtlvEnumeration::read(self.src).map_err(|err| pinpoint!(err, loc))?;
1078                    let enum_hex = format!("0x{}", hex::encode_upper(enum_val.to_be_bytes()));
1079
1080                    // Insert or replace the last value seen for this enum in our enum value lookup table
1081                    self.remember_tag_value(self.item_tag.unwrap(), &enum_hex);
1082
1083                    self.item_identifier = Some(enum_hex);
1084                }
1085
1086                visitor.visit_enum(&mut *self) // jumps to impl EnumAccess (ending at unit_variant()) below
1087            }
1088            Some(item_type) => {
1089                // "simple" enums, i.e. TTLV integer or TTLV enumeration values in the byte stream, are handled by the
1090                // case above.
1091                //
1092                // This case is for handling non-enum non-int TTLV types in the byte stream which are next to deserialize
1093                // because they match a "complex" enum variant, i.e. a tuple or struct variant that has an associated type
1094                // or types whose values are now attempintg to deserialize.
1095                //
1096                // As we can't read an enum/int value from the byte stream and use that as the item_identifier to announce
1097                // to serde we can't select the right variant. So instead we is_variant_applicable() to have been used
1098                // successfully above to grab a variant name to announce here. So if we get here and self.item_identifier
1099                // is not set then we can't announce a variant and Serde will fail to deserialize. That's fine, users
1100                // shouldn't be trying to deserialize non-TTLV-enums into Rust enums directly!
1101
1102                // This logic can handle cases such as a previously seen `BatchItem.operation` enum field whose value was
1103                // e.g. 0x00000005 which we stored in the value_store map against the tag id of the `BatchItem.operation`
1104                // field and can now use that to select a variant by naming the variant
1105                // "if <prev_tag_id> == <this_variant_id>".
1106
1107                // If we couldn't work out the correct variant name to announce to serde, don't bother going further as
1108                // that will result in `deserialize_identfier()` below calling `visitor.visit_str(identifier)` which will
1109                // then raise a `SerdeError::Other("unknown variant")` error. That isn't terrible, but it's better to
1110                // raise a `SerdeError::UnexpectedType` error here instead as really we are being asked to deserialize a
1111                // non-enum TTLV item into a Rust enum which is a type expectation mismatch.
1112                if self.item_identifier.is_none() {
1113                    let error = SerdeError::UnexpectedType {
1114                        expected: TtlvType::Enumeration,
1115                        actual: item_type,
1116                    };
1117                    Err(pinpoint!(error, self))
1118                } else {
1119                    visitor.visit_enum(&mut *self) // jumps to impl EnumAccess below
1120                }
1121            }
1122            None => {
1123                let error = SerdeError::Other(format!("TTLV item type for enum '{}' has not yet been read", name));
1124                Err(pinpoint!(error, self))
1125            }
1126        }
1127    }
1128
1129    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
1130    where
1131        V: Visitor<'de>,
1132    {
1133        if let Some(identifier) = &self.item_identifier {
1134            visitor.visit_str(identifier)
1135        } else {
1136            Err(pinpoint!(SerdeError::MissingIdentifier, self))
1137        }
1138    }
1139
1140    fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
1141    where
1142        V: Visitor<'de>,
1143    {
1144        let loc = self.location(); // See the note above about working around greedy closure capturing
1145        self.state
1146            .borrow_mut()
1147            .advance(FieldType::LengthAndValue)
1148            .map_err(|err| pinpoint!(err, loc))?;
1149        match self.item_type {
1150            Some(TtlvType::Integer) | None => {
1151                let v = TtlvInteger::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1152                visitor.visit_i32(*v)
1153            }
1154            Some(other_type) => {
1155                let error = SerdeError::UnexpectedType {
1156                    expected: TtlvType::Integer,
1157                    actual: other_type,
1158                };
1159                Err(pinpoint!(error, self))
1160            }
1161        }
1162    }
1163
1164    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
1165    where
1166        V: Visitor<'de>,
1167    {
1168        let loc = self.location(); // See the note above about working around greedy closure capturing
1169        self.state
1170            .borrow_mut()
1171            .advance(FieldType::LengthAndValue)
1172            .map_err(|err| pinpoint!(err, loc))?;
1173        match self.item_type {
1174            Some(TtlvType::LongInteger) | None => {
1175                let v = TtlvLongInteger::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1176                visitor.visit_i64(*v)
1177            }
1178            Some(TtlvType::DateTime) => {
1179                let v = TtlvDateTime::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1180                visitor.visit_i64(*v)
1181            }
1182            Some(other_type) => {
1183                let error = SerdeError::UnexpectedType {
1184                    expected: TtlvType::LongInteger,
1185                    actual: other_type,
1186                };
1187                Err(pinpoint!(error, self))
1188            }
1189        }
1190    }
1191
1192    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
1193    where
1194        V: Visitor<'de>,
1195    {
1196        let loc = self.location(); // See the note above about working around greedy closure capturing
1197        self.state
1198            .borrow_mut()
1199            .advance(FieldType::LengthAndValue)
1200            .map_err(|err| pinpoint!(err, loc))?;
1201        match self.item_type {
1202            Some(TtlvType::Boolean) | None => {
1203                let v = TtlvBoolean::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1204                visitor.visit_bool(*v)
1205            }
1206            Some(other_type) => {
1207                let error = SerdeError::UnexpectedType {
1208                    expected: TtlvType::Boolean,
1209                    actual: other_type,
1210                };
1211                Err(pinpoint!(error, self))
1212            }
1213        }
1214    }
1215
1216    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
1217    where
1218        V: Visitor<'de>,
1219    {
1220        let loc = self.location(); // See the note above about working around greedy closure capturing
1221        self.state
1222            .borrow_mut()
1223            .advance(FieldType::LengthAndValue)
1224            .map_err(|err| pinpoint!(err, loc))?;
1225        match self.item_type {
1226            Some(TtlvType::TextString) | None => {
1227                let str = TtlvTextString::read(&mut self.src).map_err(|err| pinpoint!(err, self.location()))?;
1228
1229                // Insert or replace the last value seen for this tag in our value lookup table
1230                self.remember_tag_value(self.item_tag.unwrap(), str.0.clone());
1231
1232                visitor.visit_string(str.0)
1233            }
1234            Some(other_type) => {
1235                let error = SerdeError::UnexpectedType {
1236                    expected: TtlvType::TextString,
1237                    actual: other_type,
1238                };
1239                Err(pinpoint!(error, self))
1240            }
1241        }
1242    }
1243
1244    /// Use #[serde(with = "serde_bytes")] to direct Serde to this deserializer function for type Vec<u8>.
1245    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
1246    where
1247        V: Visitor<'de>,
1248    {
1249        let loc = self.location(); // See the note above about working around greedy closure capturing
1250        self.state
1251            .borrow_mut()
1252            .advance(FieldType::LengthAndValue)
1253            .map_err(|err| pinpoint!(err, loc))?;
1254        match self.item_type {
1255            Some(TtlvType::ByteString) | Some(TtlvType::BigInteger) | None => {
1256                let v = TtlvByteString::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1257                visitor.visit_byte_buf(v.0)
1258            }
1259            Some(other_type) => {
1260                let error = SerdeError::UnexpectedType {
1261                    expected: TtlvType::ByteString,
1262                    actual: other_type,
1263                };
1264                Err(pinpoint!(error, self))
1265            }
1266        }
1267    }
1268
1269    /// Skip over the current TTLV item.
1270    ///
1271    /// When `#[serde(deny_unknown_fields)]` is not used this function is invoked by Serde derive to have us skip over
1272    /// a TTLV item for which no corresponding Rust struct field exists to deserialize it into.
1273    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
1274    where
1275        V: Visitor<'de>,
1276    {
1277        // Skip over the TTLV item. We can't just read the length and skip it because the meaning of the length is TTLV
1278        // type dependent. For some types it is the entire byte size of the TTLV item, for others it is the length of
1279        // the TTLV item value excluding padding. For TTLV Structures skip the whole structure content. For other types
1280        // deserialize them but discard the deserialized value.
1281
1282        if matches!(self.item_type.unwrap(), TtlvType::Structure) {
1283            // We're going to read the structure length and then skip it without reading the value
1284            // Reading the length advances the state machine past the length but not past the value
1285            // so we have to do that manually.
1286
1287            // Use the TTLV item length to skip the structure.
1288            let num_bytes_to_skip = TtlvDeserializer::read_length(&mut self.src, Some(&mut self.state.borrow_mut()))
1289                .map_err(|err| pinpoint!(err, self.location()))?;
1290
1291            // Skip the value bytes
1292            self.seek_forward(num_bytes_to_skip)?;
1293
1294            // Tell the state machine that we're finished reading this TTLV item
1295            self.state.borrow_mut().reset();
1296        } else {
1297            // We're going to read the value length, read the value and discard the value, all without involving
1298            // the state machine, so tell it what we are about to do.
1299            // TODO: pass the state machine to the ::read() functions instead and have them update it.
1300            let loc = self.location(); // See the note above about working around greedy closure capturing
1301            self.state
1302                .borrow_mut()
1303                .advance(FieldType::LengthAndValue)
1304                .map_err(|err| pinpoint!(err, loc))?;
1305
1306            match self.item_type.unwrap() {
1307                TtlvType::Structure => {
1308                    // We handled this case above
1309                    unreachable!()
1310                }
1311                TtlvType::Integer => {
1312                    TtlvInteger::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1313                }
1314                TtlvType::LongInteger => {
1315                    TtlvLongInteger::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1316                }
1317                TtlvType::BigInteger => {
1318                    TtlvBigInteger::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1319                }
1320                TtlvType::Enumeration => {
1321                    TtlvEnumeration::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1322                }
1323                TtlvType::Boolean => {
1324                    TtlvBoolean::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1325                }
1326                TtlvType::TextString => {
1327                    TtlvTextString::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1328                }
1329                TtlvType::ByteString => {
1330                    TtlvByteString::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1331                }
1332                TtlvType::DateTime => {
1333                    TtlvDateTime::read(&mut self.src).map_err(|err| pinpoint!(err, self))?;
1334                }
1335            }
1336        }
1337
1338        // Any visitor fn can be invoked here, they all internally return Ok(IgnoredAny).
1339        visitor.visit_none()
1340    }
1341
1342    // dummy implementations of unsupported types so that we can give back a more useful error message than when using
1343    // `forward_to_deserialize_any()` as the latter doesn't make available the type currently being deserialized into.
1344
1345    unsupported_type!(deserialize_u8, u8);
1346    unsupported_type!(deserialize_u16, u16);
1347    unsupported_type!(deserialize_u32, u32);
1348    unsupported_type!(deserialize_u64, u64);
1349    unsupported_type!(deserialize_i8, i8);
1350    unsupported_type!(deserialize_i16, i16);
1351    unsupported_type!(deserialize_f32, f32);
1352    unsupported_type!(deserialize_f64, f64);
1353    unsupported_type!(deserialize_char, char);
1354    unsupported_type!(deserialize_str, str);
1355    unsupported_type!(deserialize_map, map);
1356    unsupported_type!(deserialize_bytes, bytes);
1357    unsupported_type!(deserialize_unit, unit);
1358
1359    fn deserialize_unit_struct<V>(self, _name: &'static str, _visitor: V) -> Result<V::Value>
1360    where
1361        V: Visitor<'de>,
1362    {
1363        Err(pinpoint!(SerdeError::UnsupportedRustType("unit struct"), self))
1364    }
1365
1366    fn deserialize_tuple_struct<V>(self, _name: &'static str, _len: usize, _visitor: V) -> Result<V::Value>
1367    where
1368        V: Visitor<'de>,
1369    {
1370        Err(pinpoint!(SerdeError::UnsupportedRustType("tuple struct"), self))
1371    }
1372
1373    fn deserialize_tuple<V>(self, _len: usize, _visitor: V) -> Result<V::Value>
1374    where
1375        V: Visitor<'de>,
1376    {
1377        Err(pinpoint!(SerdeError::UnsupportedRustType("tuple"), self))
1378    }
1379
1380    fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
1381    where
1382        V: Visitor<'de>,
1383    {
1384        Err(pinpoint!(SerdeError::UnsupportedRustType("any"), self))
1385    }
1386}
1387
1388// Deserialize structure members
1389impl<'de: 'c, 'c> MapAccess<'de> for TtlvDeserializer<'de, 'c> {
1390    type Error = Error;
1391
1392    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
1393    where
1394        K: serde::de::DeserializeSeed<'de>,
1395    {
1396        if self.read_item_key(false)? {
1397            seed.deserialize(self).map(Some) // jumps to deserialize_identifier() above
1398        } else {
1399            // The end of the group was reached
1400            Ok(None)
1401        }
1402    }
1403
1404    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
1405    where
1406        V: serde::de::DeserializeSeed<'de>,
1407    {
1408        seed.deserialize(self) // jumps to deserialize_xxx() in impl Deserializer above
1409    }
1410}
1411
1412// Deserialize a Vec of one type/tag
1413impl<'de: 'c, 'c> SeqAccess<'de> for TtlvDeserializer<'de, 'c> {
1414    type Error = Error;
1415
1416    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
1417    where
1418        T: serde::de::DeserializeSeed<'de>,
1419    {
1420        if !self.read_item_key(self.group_item_count == 0)? {
1421            // The end of the containing group was reached
1422            Ok(None)
1423        } else if self.group_homogenous && (self.item_tag != self.group_tag || self.item_type != self.group_type) {
1424            // The next tag is not part of the sequence.
1425            // Walk the cursor back before the tag because we didn't consume it.
1426            self.src.set_position(self.item_start);
1427            // And reset the state machine to expect a tag again
1428            self.state.borrow_mut().reset();
1429            Ok(None)
1430        } else {
1431            // The tag and type match that of the first item in the sequence, process this element.
1432            seed.deserialize(self).map(Some) // jumps to deserialize_identifier() above
1433        }
1434    }
1435}
1436
1437// Deserialize an enum
1438impl<'de: 'c, 'c> EnumAccess<'de> for &mut TtlvDeserializer<'de, 'c> {
1439    type Error = Error;
1440    type Variant = Self;
1441
1442    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
1443    where
1444        V: serde::de::DeserializeSeed<'de>,
1445    {
1446        let val = seed.deserialize(&mut *self)?; // jumps to deserialize_identifier() above
1447        Ok((val, self)) // jumps to VariantAccess below
1448    }
1449}
1450
1451// Deserialize a variant of an enum
1452impl<'de: 'c, 'c> VariantAccess<'de> for &mut TtlvDeserializer<'de, 'c> {
1453    type Error = Error;
1454
1455    fn unit_variant(self) -> Result<()> {
1456        Ok(())
1457    }
1458
1459    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
1460    where
1461        T: serde::de::DeserializeSeed<'de>,
1462    {
1463        seed.deserialize(self)
1464    }
1465
1466    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
1467    where
1468        V: Visitor<'de>,
1469    {
1470        // The caller has provided a Rust enum variant in tuple form, i.e. SomeEnum(a, b, c), and expects us to
1471        // deserialize the right number of items to match those fields.
1472        let loc = self.location(); // See the note above about working around greedy closure capturing
1473        let seq_len = TtlvDeserializer::read_length(&mut self.src, Some(&mut self.state.borrow_mut()))
1474            .map_err(|err| pinpoint!(err, loc))?;
1475        let seq_start = self.pos() as u64;
1476        let seq_end = seq_start + (seq_len as u64);
1477
1478        let loc = self.location(); // See the note above about working around greedy closure capturing
1479        let seq_tag = TtlvDeserializer::read_tag(&mut self.src, Some(&mut self.state.borrow_mut()))
1480            .map_err(|err| pinpoint!(err, loc))?;
1481        self.item_tag = Some(seq_tag);
1482
1483        let loc = self.location(); // See the note above about working around greedy closure capturing
1484        let seq_type = TtlvDeserializer::read_type(&mut self.src, Some(&mut self.state.borrow_mut()))
1485            .map_err(|err| pinpoint!(err, loc))?;
1486        self.item_type = Some(seq_type);
1487
1488        let mut seq_cursor = self.src.clone();
1489
1490        let descendent_parser = TtlvDeserializer::from_cursor(
1491            &mut seq_cursor,
1492            self.state.clone(),
1493            seq_tag,
1494            seq_type,
1495            seq_end,
1496            &[],
1497            false, // don't require all fields in the sequence to be of the same tag and type
1498            self.tag_value_store.clone(),
1499            self.tag_path.clone(),
1500        );
1501
1502        let r = visitor.visit_seq(descendent_parser); // jumps to impl SeqAccess below
1503
1504        // The descendant parser cursor advanced but ours did not. Skip the tag that we just read.
1505        self.src.set_position(seq_cursor.position());
1506
1507        r
1508    }
1509
1510    fn struct_variant<V>(self, _fields: &'static [&'static str], _visitor: V) -> Result<V::Value>
1511    where
1512        V: Visitor<'de>,
1513    {
1514        Err(pinpoint!(SerdeError::UnsupportedRustType("struct variant"), self))
1515    }
1516}