1use alloc::{boxed::Box, string::String, vec::Vec};
3use vstd::assert_seqs_equal;
4use vstd::prelude::*;
5
6verus! {
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Structural)]
14pub enum CborFloat {
15 F16(u16),
16 F32(u32),
17 F64(u64),
18}
19
20impl DeepView for CborFloat {
21 type V = Self;
22
23 open spec fn deep_view(&self) -> Self::V {
24 *self
25 }
26}
27
28#[verifier::allow(autoderive_clone_without_spec)]
30#[derive(Debug, Clone, PartialEq, Eq)]
31pub enum CborBytes<'i> {
32 Definite(&'i [u8]),
34 Indefinite(Vec<u8>),
36}
37
38impl<'i> DeepView for CborBytes<'i> {
39 type V = Seq<u8>;
40
41 open spec fn deep_view(&self) -> Self::V {
42 match self {
43 Self::Definite(bytes) => bytes.deep_view(),
44 Self::Indefinite(bytes) => bytes.deep_view(),
45 }
46 }
47}
48
49#[verifier::allow(autoderive_clone_without_spec)]
51#[derive(Debug, Clone, PartialEq, Eq)]
52pub enum CborText<'i> {
53 Definite(&'i str),
55 Indefinite(String),
57}
58
59impl<'i> DeepView for CborText<'i> {
60 type V = Seq<char>;
61
62 open spec fn deep_view(&self) -> Self::V {
63 match self {
64 Self::Definite(text) => text.deep_view(),
65 Self::Indefinite(text) => text.deep_view(),
66 }
67 }
68}
69
70pub type CborArray<'i> = Vec<CborValue<'i>>;
72
73pub type CborMap<'i> = Vec<(CborValue<'i>, CborValue<'i>)>;
79
80#[derive(Debug, PartialEq, Eq)]
82pub enum CborValue<'i> {
83 Integer(i128),
85 Bytes(CborBytes<'i>),
86 Text(CborText<'i>),
87 Array(CborArray<'i>),
88 Map(CborMap<'i>),
89 Tag(u64, Box<CborValue<'i>>),
90 Float(CborFloat),
91 Bool(bool),
92 Null,
93 Undefined,
94 Simple(u8),
96}
97
98pub enum CborValueSpec {
103 Integer(i128),
104 Bytes(Seq<u8>),
105 Text(Seq<char>),
106 Array(Seq<CborValueSpec>),
107 Map(Seq<(CborValueSpec, CborValueSpec)>),
108 Tag(u64, Box<CborValueSpec>),
109 Float(CborFloat),
110 Bool(bool),
111 Null,
112 Undefined,
113 Simple(u8),
114}
115
116pub open spec fn cbor_value_view(value: &CborValue) -> CborValueSpec
117 decreases *value,
118{
119 match value {
120 CborValue::Integer(value) => CborValueSpec::Integer(*value),
121 CborValue::Bytes(value) => CborValueSpec::Bytes(value.deep_view()),
122 CborValue::Text(value) => CborValueSpec::Text(value.deep_view()),
123 CborValue::Array(values) => {
124 let seq = values@;
125 CborValueSpec::Array(
126 Seq::new(
127 seq.len(),
128 |i: int|
129 {
130 if 0 <= i < seq.len() {
131 cbor_value_view(&seq[i])
132 } else {
133 arbitrary()
134 }
135 },
136 ),
137 )
138 },
139 CborValue::Map(values) => {
140 let seq = values@;
141 CborValueSpec::Map(
142 Seq::new(
143 seq.len(),
144 |i: int|
145 {
146 if 0 <= i < seq.len() {
147 (cbor_value_view(&seq[i].0), cbor_value_view(&seq[i].1))
148 } else {
149 arbitrary()
150 }
151 },
152 ),
153 )
154 },
155 CborValue::Tag(tag, value) => {
156 CborValueSpec::Tag(*tag, Box::new(cbor_value_view(&**value)))
157 },
158 CborValue::Float(value) => CborValueSpec::Float(*value),
159 CborValue::Bool(value) => CborValueSpec::Bool(*value),
160 CborValue::Null => CborValueSpec::Null,
161 CborValue::Undefined => CborValueSpec::Undefined,
162 CborValue::Simple(value) => CborValueSpec::Simple(*value),
163 }
164}
165
166impl<'i> DeepView for CborValue<'i> {
167 type V = CborValueSpec;
168
169 open spec fn deep_view(&self) -> Self::V {
170 cbor_value_view(self)
171 }
172}
173
174pub proof fn lemma_collection_value_view(value: &CborValue)
177 ensures
178 match value {
179 CborValue::Array(values) => {
180 cbor_value_view(value) == CborValueSpec::Array(values.deep_view())
181 },
182 CborValue::Map(entries) => {
183 cbor_value_view(value) == CborValueSpec::Map(entries.deep_view())
184 },
185 _ => true,
186 },
187 decreases *value,
188{
189 match value {
190 CborValue::Array(values) => {
191 let viewed = cbor_value_view(value);
192 let actual = match viewed {
193 CborValueSpec::Array(s) => s,
194 _ => arbitrary(),
195 };
196 assert_seqs_equal!(actual, values.deep_view(), i => {});
197 assert(viewed == CborValueSpec::Array(actual));
198 },
199 CborValue::Map(entries) => {
200 let viewed = cbor_value_view(value);
201 let actual = match viewed {
202 CborValueSpec::Map(s) => s,
203 _ => arbitrary(),
204 };
205 assert_seqs_equal!(actual, entries.deep_view(), i => {});
206 assert(viewed == CborValueSpec::Map(actual));
207 },
208 _ => {},
209 }
210}
211
212}