1use super::*;
2use vstd::prelude::*;
3
4verus! {
5
6#[derive(Debug, View)]
14pub struct Optional<C1, C2>(pub C1, pub C2);
15
16pub type OptionalValue<T1, T2> = PairValue<OptionDeep<T1>, T2>;
17
18impl<C1, C2> SpecCombinator for Optional<C1, C2> where
19 C1: SecureSpecCombinator,
20 C2: SecureSpecCombinator + DisjointFrom<C1>,
21{
22 type SpecResult = PairValue<OptionDeep<C1::SpecResult>, C2::SpecResult>;
23
24 closed spec fn spec_parse(&self, s: Seq<u8>) -> Result<(usize, Self::SpecResult), ()>
25 {
26 if self.1.disjoint_from(&self.0) {
27 if let Ok((n, (v1, v2))) = (self.0, self.1).spec_parse(s) {
28 Ok((n, PairValue(OptionDeep::Some(v1), v2)))
29 } else if let Ok((n, v)) = self.1.spec_parse(s) {
30 Ok((n, PairValue(OptionDeep::None, v)))
31 } else {
32 Err(())
33 }
34 } else {
35 Err(())
36 }
37 }
38
39 proof fn spec_parse_wf(&self, s: Seq<u8>) {
40 (self.0, self.1).spec_parse_wf(s);
41 self.1.spec_parse_wf(s);
42 }
43
44 closed spec fn spec_serialize(&self, v: Self::SpecResult) -> Result<Seq<u8>, ()>
45 {
46 if self.1.disjoint_from(&self.0) {
47 match v {
48 PairValue(OptionDeep::Some(v1), v2) => (self.0, self.1).spec_serialize((v1, v2)),
49 PairValue(OptionDeep::None, v2) => self.1.spec_serialize(v2),
50 }
51 } else {
52 Err(())
53 }
54 }
55}
56
57impl<C1, C2> SecureSpecCombinator for Optional<C1, C2> where
58 C1: SecureSpecCombinator,
59 C2: SecureSpecCombinator + DisjointFrom<C1>
60{
61 open spec fn is_prefix_secure() -> bool {
62 C1::is_prefix_secure() && C2::is_prefix_secure()
63 }
64
65 proof fn theorem_serialize_parse_roundtrip(&self, v: Self::SpecResult) {
66 match v {
67 PairValue(OptionDeep::Some(v1), v2) => {
68 (self.0, self.1).theorem_serialize_parse_roundtrip((v1, v2));
69 },
70 PairValue(OptionDeep::None, v2) => {
71 if let Ok(buf) = self.1.spec_serialize(v2) {
72 if self.1.disjoint_from(&self.0) {
73 self.1.parse_disjoint_on(&self.0, buf);
74 }
75 }
76 self.1.theorem_serialize_parse_roundtrip(v2);
77 },
78 }
79 }
80
81 proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
82 (self.0, self.1).theorem_parse_serialize_roundtrip(buf);
83 self.1.theorem_parse_serialize_roundtrip(buf);
84 assert(self.spec_parse(buf) matches Ok((n, v)) ==> self.spec_serialize(v).unwrap() == buf.subrange(0, n as int));
85 }
86
87 proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
88 if self.1.disjoint_from(&self.0) {
89 self.1.parse_disjoint_on(&self.0, s1.add(s2));
90 (self.0, self.1).lemma_prefix_secure(s1, s2);
91 self.1.lemma_prefix_secure(s1, s2);
92 }
93 }
94}
95
96impl<C1, C2> Combinator for Optional<C1, C2> where
97 C1: Combinator,
98 C2: Combinator,
99
100 C1::V: SecureSpecCombinator<SpecResult = <C1::Owned as View>::V>,
101 C2::V: SecureSpecCombinator<SpecResult = <C2::Owned as View>::V> + DisjointFrom<C1::V>,
102{
103 type Result<'a> = OptionalValue<C1::Result<'a>, C2::Result<'a>>;
104 type Owned = OptionalValue<C1::Owned, C2::Owned>;
105
106 closed spec fn spec_length(&self) -> Option<usize> {
107 None
108 }
109
110 fn length(&self) -> Option<usize> {
111 None
112 }
113
114 open spec fn parse_requires(&self) -> bool {
115 &&& self.0.parse_requires()
116 &&& self.1.parse_requires()
117 &&& self.1@.disjoint_from(&self.0@)
118 &&& C1::V::is_prefix_secure()
119 }
120
121 #[inline(always)]
122 fn parse<'a>(&self, s: &'a [u8]) -> (res: Result<(usize, Self::Result<'a>), ParseError>) {
123 let res = if let Ok((n, (v1, v2))) = (&self.0, &self.1).parse(s) {
124 Ok((n, PairValue(OptionDeep::Some(v1), v2)))
125 } else if let Ok((n, v2)) = self.1.parse(s) {
126 Ok((n, PairValue(OptionDeep::None, v2)))
127 } else {
128 Err(ParseError::OrdChoiceNoMatch)
129 };
130
131 assert(res matches Ok((n, v)) ==> {
133 &&& self@.spec_parse(s@) is Ok
134 &&& self@.spec_parse(s@) matches Ok((m, w)) ==> n == m && v@ == w && n <= s@.len()
135 });
136
137 res
138 }
139
140 open spec fn serialize_requires(&self) -> bool {
141 &&& self.0.serialize_requires()
142 &&& self.1.serialize_requires()
143 &&& self.1@.disjoint_from(&self.0@)
144 &&& C1::V::is_prefix_secure()
145 }
146
147 #[inline(always)]
148 fn serialize(&self, v: Self::Result<'_>, data: &mut Vec<u8>, pos: usize) -> (res: Result<usize, SerializeError>) {
149 let len = match v {
150 PairValue(OptionDeep::Some(v1), v2) => (&self.0, &self.1).serialize((v1, v2), data, pos),
151 PairValue(OptionDeep::None, v2) => self.1.serialize(v2, data, pos),
152 }?;
153
154 assert(data@ =~= seq_splice(old(data)@, pos, self@.spec_serialize(v@).unwrap()));
155
156 Ok(len)
157 }
158}
159
160impl<T1, T2, T3> DisjointFrom<T1> for Optional<T2, T3> where
163 T1: SecureSpecCombinator,
164 T2: SecureSpecCombinator,
165 T3: SecureSpecCombinator,
166 T2: DisjointFrom<T1>,
167 T3: DisjointFrom<T1>,
168 T3: DisjointFrom<T2>,
169{
170 open spec fn disjoint_from(&self, other: &T1) -> bool {
171 self.0.disjoint_from(other) &&
172 self.1.disjoint_from(other)
173 }
174
175 proof fn parse_disjoint_on(&self, other: &T1, buf: Seq<u8>) {
176 self.0.parse_disjoint_on(other, buf);
177 self.1.parse_disjoint_on(other, buf);
178 }
179}
180
181}