1use crate::core::exec::output::*;
3use crate::core::{
4 exec::{
5 parser::{PResult, Parser},
6 serializer::{ByteLen, ComplianceErrorKind, PreSerializeError, Prepare, Serializer},
7 ParseErrorKind,
8 },
9 spec::{Consistency, SpecByteLen, SpecParser, SpecSerializer},
10};
11use vstd::prelude::*;
12use OutputBuf;
13
14verus! {
15
16impl<A: View, B: View> View for super::Sum<A, B> {
17 type V = super::Sum<A::V, B::V>;
18
19 open spec fn view(&self) -> Self::V {
20 match self {
21 super::Sum::Inl(a) => super::Sum::Inl(a@),
22 super::Sum::Inr(b) => super::Sum::Inr(b@),
23 }
24 }
25}
26
27impl<A: DeepView, B: DeepView> DeepView for super::Sum<A, B> {
28 type V = super::Sum<A::V, B::V>;
29
30 open spec fn deep_view(&self) -> Self::V {
31 match self {
32 super::Sum::Inl(a) => super::Sum::Inl(a.deep_view()),
33 super::Sum::Inr(b) => super::Sum::Inr(b.deep_view()),
34 }
35 }
36}
37
38impl<I, A, B> Parser<I> for super::Choice<A, B> where
39 I: View<V = Seq<u8>>,
40 A: Parser<I>,
41 B: Parser<I>,
42 {
43 type PT = super::Sum<A::PT, B::PT>;
44
45 fn min_byte_len(&self) -> usize {
46 let a = self.0.min_byte_len();
47 let b = self.1.min_byte_len();
48 if a < b {
49 a
50 } else {
51 b
52 }
53 }
54
55 open spec fn exec_inv(&self) -> bool {
56 &&& self.0.exec_inv()
57 &&& self.1.exec_inv()
58 }
59
60 fn parse(&self, ibuf: &I) -> PResult<Self::PT> {
61 match self.0.parse(ibuf) {
62 Ok((n, v)) => Ok((n, super::Sum::Inl(v))),
63 Err(first_err) => {
64 match self.1.parse(ibuf) {
65 Ok((n, v)) => {
66 let inr_v = super::Sum::Inr(v);
67 assert(self.spec_parse(ibuf@) == Some((n as int, inr_v.deep_view())));
68 Ok((n, inr_v))
69 },
70 Err(second_err) => {
71 match first_err.kind {
72 ParseErrorKind::RecursionLimitExceeded => Err(first_err),
73 _ => Err(second_err),
74 }
75 },
76 }
77 },
78 }
79 }
80}
81
82impl<Output: OutputBuf, A, B, TA, TB> Serializer<Output, super::Sum<TA, TB>> for super::Choice<
83 A,
84 B,
85> where TA: DeepView, TB: DeepView, A: Serializer<Output, TA>, B: Serializer<Output, TB> {
86 #[verifier::prophetic]
87 open spec fn exec_inv(&self) -> bool {
88 &&& self.0.exec_inv()
89 &&& self.1.exec_inv()
90 }
91
92 fn serialize_into(&self, v: &super::Sum<TA, TB>, obuf: &mut Output) {
93 match v {
94 super::Sum::Inl(va) => self.0.serialize_into(va, obuf),
95 super::Sum::Inr(vb) => self.1.serialize_into(vb, obuf),
96 }
97 }
98}
99
100impl<A, B, TA, TB> ByteLen<super::Sum<TA, TB>> for super::Choice<A, B> where
101 TA: DeepView,
102 TB: DeepView,
103 A: ByteLen<TA>,
104 B: ByteLen<TB>,
105 {
106 open spec fn exec_inv(&self) -> bool {
107 &&& self.0.exec_inv()
108 &&& self.1.exec_inv()
109 }
110
111 fn length(&self, v: &super::Sum<TA, TB>) -> (len: usize) {
112 match v {
113 super::Sum::Inl(va) => self.0.length(va),
114 super::Sum::Inr(vb) => self.1.length(vb),
115 }
116 }
117}
118
119impl<A, B, TA, TB> Prepare<super::Sum<TA, TB>> for super::Choice<A, B> where
120 TA: DeepView,
121 TB: DeepView,
122 A: Prepare<TA>,
123 B: Prepare<TB>,
124 {
125 open spec fn exec_inv(&self) -> bool {
126 &&& self.0.exec_inv()
127 &&& self.1.exec_inv()
128 }
129
130 fn prepare(&self, v: &super::Sum<TA, TB>) -> (checked: Result<usize, PreSerializeError>) {
131 match v {
132 super::Sum::Inl(va) => self.0.prepare(va),
133 super::Sum::Inr(vb) => self.1.prepare(vb),
134 }
135 }
136}
137
138impl<const NONDETERMINISTIC: bool, I, A, B> Parser<I> for super::Alt<A, B, NONDETERMINISTIC> where
139 I: View<V = Seq<u8>>,
140 A: Parser<I>,
141 B: Parser<I, PVal = A::PVal, PT = A::PT>,
142 {
143 type PT = A::PT;
144
145 fn min_byte_len(&self) -> usize {
146 let a = self.0.min_byte_len();
147 let b = self.1.min_byte_len();
148 if a < b {
149 a
150 } else {
151 b
152 }
153 }
154
155 open spec fn exec_inv(&self) -> bool {
156 &&& self.0.exec_inv()
157 &&& self.1.exec_inv()
158 }
159
160 fn parse(&self, ibuf: &I) -> PResult<Self::PT> {
161 match self.0.parse(ibuf) {
162 Ok(r) => Ok(r),
163 Err(_) => self.1.parse(ibuf),
164 }
165 }
166}
167
168impl<I, A, B> Parser<I> for super::Sum<A, B> where
169 I: View<V = Seq<u8>>,
170 A: Parser<I>,
171 B: Parser<I>,
172 {
173 type PT = super::Sum<A::PT, B::PT>;
174
175 fn min_byte_len(&self) -> usize {
176 match self {
178 super::Sum::Inl(a) => a.min_byte_len(),
179 super::Sum::Inr(b) => b.min_byte_len(),
180 }
181 }
182
183 open spec fn exec_inv(&self) -> bool {
184 match self {
185 super::Sum::Inl(a) => a.exec_inv(),
186 super::Sum::Inr(b) => b.exec_inv(),
187 }
188 }
189
190 fn parse(&self, ibuf: &I) -> PResult<Self::PT> {
191 match self {
192 super::Sum::Inl(a) => {
193 let (n, v) = a.parse(ibuf)?;
194 Ok((n, super::Sum::Inl(v)))
195 },
196 super::Sum::Inr(b) => {
197 let (n, v) = b.parse(ibuf)?;
198 Ok((n, super::Sum::Inr(v)))
199 },
200 }
201 }
202}
203
204impl<Output: OutputBuf, A, B, TA, TB> Serializer<Output, super::Sum<TA, TB>> for super::Sum<
205 A,
206 B,
207> where TA: DeepView, TB: DeepView, A: Serializer<Output, TA>, B: Serializer<Output, TB> {
208 #[verifier::prophetic]
209 open spec fn exec_inv(&self) -> bool {
210 match self {
211 super::Sum::Inl(a) => a.exec_inv(),
212 super::Sum::Inr(b) => b.exec_inv(),
213 }
214 }
215
216 fn serialize_into(&self, v: &super::Sum<TA, TB>, obuf: &mut Output) {
217 match (self, v) {
218 (super::Sum::Inl(a), super::Sum::Inl(va)) => a.serialize_into(va, obuf),
219 (super::Sum::Inr(b), super::Sum::Inr(vb)) => b.serialize_into(vb, obuf),
220 _ => (),
221 }
222 }
223}
224
225impl<A, B, TA, TB> ByteLen<super::Sum<TA, TB>> for super::Sum<A, B> where
226 TA: DeepView,
227 TB: DeepView,
228 A: ByteLen<TA>,
229 B: ByteLen<TB>,
230 {
231 open spec fn exec_inv(&self) -> bool {
232 match self {
233 super::Sum::Inl(a) => a.exec_inv(),
234 super::Sum::Inr(b) => b.exec_inv(),
235 }
236 }
237
238 fn length(&self, v: &super::Sum<TA, TB>) -> (len: usize) {
239 match (self, v) {
240 (super::Sum::Inl(a), super::Sum::Inl(va)) => a.length(va),
241 (super::Sum::Inr(b), super::Sum::Inr(vb)) => b.length(vb),
242 _ => 0,
243 }
244 }
245}
246
247impl<A, B, TA, TB> Prepare<super::Sum<TA, TB>> for super::Sum<A, B> where
248 TA: DeepView,
249 TB: DeepView,
250 A: Prepare<TA>,
251 B: Prepare<TB>,
252 {
253 open spec fn exec_inv(&self) -> bool {
254 match self {
255 super::Sum::Inl(a) => a.exec_inv(),
256 super::Sum::Inr(b) => b.exec_inv(),
257 }
258 }
259
260 fn prepare(&self, v: &super::Sum<TA, TB>) -> (checked: Result<usize, PreSerializeError>) {
261 match (self, v) {
262 (super::Sum::Inl(a), super::Sum::Inl(va)) => a.prepare(va),
263 (super::Sum::Inr(b), super::Sum::Inr(vb)) => b.prepare(vb),
264 _ => Err(PreSerializeError::not_compliant(ComplianceErrorKind::InvalidChoice)),
265 }
266 }
267}
268
269}