tlv_parser/
lib.rs

1#![no_std]
2
3//! A library to parse and emit [BER-TLV](https://en.wikipedia.org/wiki/X.690#BER_encoding) data.
4//!
5//! #Examples
6//!
7//! Parse TLV:
8//!
9//! ```
10//! use tlv_parser::tlv::{Tlv, Value};
11//!
12//! let input: Vec<u8> = vec![0x21, 0x05, 0x22, 0x03, 0x03, 0x01, 0xaa];
13//! let tlv = Tlv::from_vec( &input ).unwrap();
14//!
15//! if let Some(&Value::Val(ref val)) = tlv.find_val("21 / 22 / 03") {
16//!     assert_eq!(*val, vec![0xaa]);
17//! }
18//! ```
19//!
20//! Emit constructed TLV incapsulated primitive TLV:
21//!
22//! ```
23//! use tlv_parser::tlv::*;
24//!
25//! let primitive_tlv = Tlv::new(0x01, Value::Nothing).unwrap();
26//! let constructed_tlv = Tlv::new(0x21, Value::TlvList(vec![primitive_tlv])).unwrap();
27//!
28//! assert_eq!(constructed_tlv.to_vec(), vec![0x21, 0x02, 0x01, 0x00]);
29//! ```
30
31extern crate alloc;
32
33pub mod tlv;
34
35type Result<T> = core::result::Result<T, TlvError>;
36
37#[derive(Debug)]
38pub enum TlvError {
39    TruncatedTlv,
40    InvalidLength,
41    InvalidTagNumber,
42    TooShortBody { expected: usize, found: usize },
43    ValExpected { tag_number: usize },
44    TagPathError,
45}
46
47use core::fmt;
48
49impl fmt::Display for TlvError {
50    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51        use TlvError::*;
52
53        match self {
54            TruncatedTlv => write!(f, "Too short input vector"),
55            InvalidLength => writeln!(f, "Invalid length value"),
56            InvalidTagNumber => write!(f, "Invalid tag number"),
57            TooShortBody { expected, found } => {
58                write!(f, "Too short body: expected {expected}, found {found}")
59            }
60            ValExpected { tag_number } => write!(
61                f,
62                "Tag number defines primitive TLV, but value is not Value::Val: {tag_number}"
63            ),
64            TagPathError => write!(f, "Provided 'tag-path' has error"),
65        }
66    }
67}
68
69impl core::error::Error for TlvError {}