1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use crate::context::{BasicContext, Context};
use crate::flatten::flatten_from_str;
use crate::ivt::Node;
use crate::util::{make_oops, ValidateError, ValidateResult};
use crate::validate::validate;
use crate::value::Value;
use serde_cbor::Value as CBOR_Value;
use std::collections::BTreeMap;
use std::convert::TryFrom;
impl TryFrom<&CBOR_Value> for Value {
type Error = ValidateError;
fn try_from(value: &CBOR_Value) -> Result<Self, Self::Error> {
let result = match value {
CBOR_Value::Null => Value::Null,
CBOR_Value::Bool(b) => Value::Bool(*b),
CBOR_Value::Integer(i) => Value::Integer(*i),
CBOR_Value::Float(f) => Value::from_float(*f),
CBOR_Value::Bytes(b) => Value::Bytes(b.clone()),
CBOR_Value::Text(t) => Value::Text(t.clone()),
CBOR_Value::Array(a) => {
let array: Result<_, _> = a.iter().map(Value::try_from).collect();
Value::Array(array?)
}
CBOR_Value::Map(m) => {
type MapTree = BTreeMap<Value, Value>;
let map: Result<MapTree, _> = m
.iter()
.map(|(k, v)| {
Ok((Value::try_from(k)?, Value::try_from(v)?))
})
.collect();
Value::Map(map?)
}
_ => {
return make_oops("can't handle hidden cbor Value");
}
};
Ok(result)
}
}
impl TryFrom<CBOR_Value> for Value {
type Error = ValidateError;
fn try_from(value: CBOR_Value) -> Result<Self, Self::Error> {
Value::try_from(&value)
}
}
pub fn validate_cbor(node: &Node, value: &CBOR_Value, ctx: &dyn Context) -> ValidateResult {
let value = Value::try_from(value)?;
validate(&value, node, ctx)
}
pub fn validate_cbor_bytes(name: &str, cddl: &str, cbor: &[u8]) -> ValidateResult {
let flat_cddl = flatten_from_str(cddl)?;
let ctx = BasicContext::new(flat_cddl);
let rule_node: &Node = ctx.rules.get(name).ok_or_else(|| {
let msg = format!("rule/group lookup failure: {}", name);
ValidateError::Oops(msg)
})?;
let cbor_value: CBOR_Value = serde_cbor::from_slice(cbor).map_err(|e| {
let msg = format!("cbor parsing failed: {}", e);
ValidateError::Oops(msg)
})?;
let value = Value::try_from(cbor_value)?;
validate(&value, rule_node, &ctx)
}