openpgp_card/ocard/tlv/
value.rs

1// SPDX-FileCopyrightText: 2021 Heiko Schaefer <heiko@schaefer.name>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! Value in a TLV data structure
5
6use crate::ocard::data::complete;
7use crate::ocard::tlv::Tlv;
8
9/// A TLV "value"
10#[derive(Debug, Eq, PartialEq)]
11pub enum Value {
12    /// A "constructed" value, consisting of a list of Tlv
13    C(Vec<Tlv>),
14
15    /// A "simple" value, consisting of binary data
16    S(Vec<u8>),
17}
18
19impl Value {
20    pub(crate) fn parse(data: &[u8], constructed: bool) -> nom::IResult<&[u8], Self> {
21        match constructed {
22            false => Ok((&[], Value::S(data.to_vec()))),
23            true => {
24                let mut c = vec![];
25                let mut input = data;
26
27                while !input.is_empty() {
28                    let (rest, tlv) = Tlv::parse(input)?;
29                    input = rest;
30                    c.push(tlv);
31                }
32
33                Ok((&[], Value::C(c)))
34            }
35        }
36    }
37
38    pub fn from(data: &[u8], constructed: bool) -> Result<Self, crate::Error> {
39        complete(Self::parse(data, constructed))
40    }
41
42    pub fn serialize(&self) -> Vec<u8> {
43        match self {
44            Value::S(data) => data.clone(),
45            Value::C(data) => {
46                let mut s = vec![];
47                for t in data {
48                    s.extend(&t.serialize());
49                }
50                s
51            }
52        }
53    }
54}