dcbor_parse/
compose.rs

1use dcbor::prelude::*;
2use thiserror::Error;
3
4use crate::{ParseError, parse_dcbor_item};
5
6#[derive(Debug, Error, Clone, PartialEq)]
7#[rustfmt::skip]
8pub enum Error {
9    #[error("Invalid odd map length")]
10    OddMapLength,
11    #[error("Duplicate map key")]
12    DuplicateMapKey,
13    #[error("Invalid CBOR item: {0}")]
14    ParseError(#[from] ParseError),
15}
16
17pub type Result<T> = std::result::Result<T, Error>;
18
19/// Composes a dCBOR array from a slice of string slices, and returns a CBOR
20/// object representing the array.
21///
22/// Each string slice is parsed as a dCBOR item.
23///
24/// # Example
25///
26/// ```rust
27/// # use dcbor_parse::compose_dcbor_array;
28/// let cbor = compose_dcbor_array(&["1", "2", "3"]).unwrap();
29/// assert_eq!(cbor.diagnostic(), "[1, 2, 3]");
30/// ```
31pub fn compose_dcbor_array(array: &[&str]) -> Result<CBOR> {
32    let mut result = Vec::new();
33    for item in array {
34        let cbor = parse_dcbor_item(item)?;
35        result.push(cbor);
36    }
37    Ok(result.into())
38}
39
40/// Composes a dCBOR map from a slice of string slices, and returns a CBOR
41/// object representing the map.
42///
43/// The length of the slice must be even, as each key must have a corresponding
44/// value.
45///
46/// Each string slice is parsed as a dCBOR item.
47///
48/// # Example
49///
50/// ```rust
51/// # use dcbor_parse::compose_dcbor_map;
52/// let cbor = compose_dcbor_map(&["1", "2", "3", "4"]).unwrap();
53/// assert_eq!(cbor.diagnostic(), "{1: 2, 3: 4}");
54/// ```
55pub fn compose_dcbor_map(array: &[&str]) -> Result<CBOR> {
56    if !array.len().is_multiple_of(2) {
57        return Err(Error::OddMapLength);
58    }
59
60    let mut map = Map::new();
61
62    for i in (0..array.len()).step_by(2) {
63        let key = parse_dcbor_item(array[i])?;
64        let value = parse_dcbor_item(array[i + 1])?;
65
66        // Check for duplicate key
67        if map.contains_key(key.clone()) {
68            return Err(Error::DuplicateMapKey);
69        }
70
71        map.insert(key, value);
72    }
73
74    Ok(map.into())
75}