vest_lib/regular/variant.rs
1use super::disjoint::DisjointFrom;
2use crate::properties::*;
3use vstd::prelude::*;
4
5verus! {
6
7#[allow(missing_docs)]
8#[derive(Debug)]
9pub enum Either<A, B> {
10 Left(A),
11 Right(B),
12}
13
14impl<A: View, B: View> View for Either<A, B> {
15 type V = Either<A::V, B::V>;
16
17 open spec fn view(&self) -> Either<A::V, B::V> {
18 match self {
19 Either::Left(v) => Either::Left(v@),
20 Either::Right(v) => Either::Right(v@),
21 }
22 }
23}
24
25/// Combinator that tries the `Fst` combinator and if it fails, tries the `Snd` combinator.
26pub struct Choice<Fst, Snd>(pub Fst, pub Snd);
27
28impl<Fst, Snd> Choice<Fst, Snd> where
29 Fst: View,
30 Snd: View,
31 Fst::V: SpecCombinator,
32 Snd::V: SpecCombinator,
33 Snd::V: DisjointFrom<Fst::V>,
34 {
35 pub fn new(fst: Fst, snd: Snd) -> (o: Self)
36 requires
37 snd@.disjoint_from(&fst@),
38 ensures
39 o == Choice(fst, snd),
40 {
41 Choice(fst, snd)
42 }
43}
44
45impl<Fst: View, Snd: View> View for Choice<Fst, Snd> where {
46 type V = Choice<Fst::V, Snd::V>;
47
48 open spec fn view(&self) -> Self::V {
49 Choice(self.0@, self.1@)
50 }
51}
52
53impl<Fst, Snd> SpecCombinator for Choice<Fst, Snd> where
54 Fst: SpecCombinator,
55 Snd: SpecCombinator + DisjointFrom<Fst>,
56 {
57 type Type = Either<Fst::Type, Snd::Type>;
58
59 open spec fn requires(&self) -> bool {
60 self.0.requires() && self.1.requires() && self.1.disjoint_from(&self.0)
61 }
62
63 open spec fn wf(&self, v: Self::Type) -> bool {
64 match v {
65 Either::Left(v) => self.0.wf(v),
66 Either::Right(v) => self.1.wf(v),
67 }
68 }
69
70 open spec fn spec_parse(&self, s: Seq<u8>) -> Option<(int, Self::Type)> {
71 if let Some((n, v)) = self.0.spec_parse(s) {
72 Some((n, Either::Left(v)))
73 } else {
74 if let Some((n, v)) = self.1.spec_parse(s) {
75 Some((n, Either::Right(v)))
76 } else {
77 None
78 }
79 }
80 }
81
82 open spec fn spec_serialize(&self, v: Self::Type) -> Seq<u8> {
83 match v {
84 Either::Left(v) => self.0.spec_serialize(v),
85 Either::Right(v) => self.1.spec_serialize(v),
86 }
87 }
88}
89
90impl<Fst, Snd> SecureSpecCombinator for Choice<Fst, Snd> where
91 Fst: SecureSpecCombinator,
92 Snd: SecureSpecCombinator + DisjointFrom<Fst>,
93 {
94 open spec fn is_prefix_secure() -> bool {
95 Fst::is_prefix_secure() && Snd::is_prefix_secure()
96 }
97
98 open spec fn is_productive(&self) -> bool {
99 self.0.is_productive() && self.1.is_productive()
100 }
101
102 proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
103 if self.1.disjoint_from(&self.0) {
104 // must also explicitly state that parser1 will fail on anything that parser2 will succeed on
105 self.1.parse_disjoint_on(&self.0, s1.add(s2));
106 if Self::is_prefix_secure() {
107 self.0.lemma_prefix_secure(s1, s2);
108 self.1.lemma_prefix_secure(s1, s2);
109 }
110 }
111 }
112
113 proof fn theorem_serialize_parse_roundtrip(&self, v: Self::Type) {
114 match v {
115 Either::Left(v) => {
116 self.0.theorem_serialize_parse_roundtrip(v);
117 },
118 Either::Right(v) => {
119 self.1.theorem_serialize_parse_roundtrip(v);
120 let buf = self.1.spec_serialize(v);
121 if self.1.disjoint_from(&self.0) {
122 self.1.parse_disjoint_on(&self.0, buf);
123 }
124 },
125 }
126 }
127
128 proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
129 if let Some((n, v)) = self.0.spec_parse(buf) {
130 self.0.theorem_parse_serialize_roundtrip(buf);
131 } else {
132 if let Some((n, v)) = self.1.spec_parse(buf) {
133 self.1.theorem_parse_serialize_roundtrip(buf);
134 }
135 }
136 }
137
138 proof fn lemma_parse_length(&self, s: Seq<u8>) {
139 if let Some((n, v)) = self.0.spec_parse(s) {
140 self.0.lemma_parse_length(s);
141 } else {
142 if let Some((n, v)) = self.1.spec_parse(s) {
143 self.1.lemma_parse_length(s);
144 }
145 }
146 }
147
148 proof fn lemma_parse_productive(&self, s: Seq<u8>) {
149 if let Some((n, v)) = self.0.spec_parse(s) {
150 self.0.lemma_parse_productive(s);
151 } else {
152 if let Some((n, v)) = self.1.spec_parse(s) {
153 self.1.lemma_parse_productive(s);
154 }
155 }
156 }
157}
158
159impl<'x, I, O, Fst, Snd> Combinator<'x, I, O> for Choice<Fst, Snd> where
160 I: VestInput,
161 O: VestOutput<I>,
162 Fst: Combinator<'x, I, O>,
163 Snd: Combinator<'x, I, O>,
164 Fst::V: SecureSpecCombinator<Type = <Fst::Type as View>::V>,
165 Snd::V: SecureSpecCombinator<Type = <Snd::Type as View>::V>,
166 Snd::V: DisjointFrom<Fst::V>,
167 {
168 type Type = Either<Fst::Type, Snd::Type>;
169
170 type SType = Either<Fst::SType, Snd::SType>;
171
172 fn length(&self, v: Self::SType) -> usize {
173 match v {
174 Either::Left(v) => self.0.length(v),
175 Either::Right(v) => self.1.length(v),
176 }
177 }
178
179 open spec fn ex_requires(&self) -> bool {
180 self.0.ex_requires() && self.1.ex_requires()
181 }
182
183 fn parse(&self, s: I) -> (res: Result<(usize, Self::Type), ParseError>) {
184 if let Ok((n, v)) = self.0.parse(s.clone()) {
185 Ok((n, Either::Left(v)))
186 } else {
187 if let Ok((n, v)) = self.1.parse(s) {
188 Ok((n, Either::Right(v)))
189 } else {
190 Err(ParseError::OrdChoiceNoMatch)
191 }
192 }
193 }
194
195 fn serialize(&self, v: Self::SType, data: &mut O, pos: usize) -> (res: Result<
196 usize,
197 SerializeError,
198 >) {
199 match v {
200 Either::Left(v) => {
201 let n = self.0.serialize(v, data, pos)?;
202 Ok(n)
203 },
204 Either::Right(v) => {
205 let n = self.1.serialize(v, data, pos)?;
206 Ok(n)
207 },
208 }
209 }
210}
211
212/// The optional combinator that never fails.
213/// If the inner combinator fails, the result is `None`.
214///
215/// ## Note
216///
217/// One might think that the `Opt<T>` combinator can be encoded as `OrdChoice<T, Success>`.
218/// However, this is not the case because one cannot prove that `Success` is disjoint from `T`.
219/// In fact, there is a fundamental difference between `Opt<T>` and `OrdChoice<Fst, Snd>`:
220/// the `Disjoint` conditions can be aggregated for `OrdChoice`, making it "nestable", while
221/// the "productivity" condition cannot be aggregated for `Opt` (i.e., `Opt<Opt<T>>` can never be
222/// constructed).
223pub struct Opt<T>(pub T);
224
225impl<T: View> View for Opt<T> where {
226 type V = Opt<T::V>;
227
228 open spec fn view(&self) -> Self::V {
229 Opt(self.0@)
230 }
231}
232
233impl<C: View> Opt<C> where C::V: SecureSpecCombinator {
234 /// Constructs a new `Opt` combinator, only if the inner combinator is productive.
235 pub fn new(c: C) -> (o: Self)
236 requires
237 c@.is_productive(),
238 ensures
239 o == Opt(c),
240 {
241 Opt(c)
242 }
243}
244
245/// Wrapper for the `core::option::Option` type.
246/// Needed because currently Verus does not implement the `View` trait for `Option`.
247#[derive(Debug, PartialEq, Eq)]
248pub struct Optional<T>(pub Option<T>);
249
250impl<T: Clone> Clone for Optional<T> {
251 fn clone(&self) -> Self {
252 Optional(self.0.clone())
253 }
254}
255
256impl<T: View> View for Optional<T> where {
257 type V = Option<T::V>;
258
259 open spec fn view(&self) -> Self::V {
260 match &self.0 {
261 Some(v) => Some(v@),
262 None => None,
263 }
264 }
265}
266
267impl<T: SecureSpecCombinator> SpecCombinator for Opt<T> where {
268 type Type = Option<T::Type>;
269
270 open spec fn requires(&self) -> bool {
271 self.0.requires() && self.0.is_productive()
272 }
273
274 open spec fn wf(&self, v: Self::Type) -> bool {
275 match v {
276 Some(vv) => self.0.wf(vv),
277 None => true,
278 }
279 }
280
281 open spec fn spec_parse(&self, s: Seq<u8>) -> Option<(int, Self::Type)> {
282 if let Some((n, v)) = self.0.spec_parse(s) {
283 Some((n, Some(v)))
284 } else {
285 Some((0, None))
286 }
287 }
288
289 open spec fn spec_serialize(&self, v: Self::Type) -> Seq<u8> {
290 match v {
291 Some(v) => self.0.spec_serialize(v),
292 None => Seq::empty(),
293 }
294 }
295}
296
297impl<T: SecureSpecCombinator> SecureSpecCombinator for Opt<T> where {
298 open spec fn is_prefix_secure() -> bool {
299 false
300 }
301
302 open spec fn is_productive(&self) -> bool {
303 false
304 }
305
306 proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
307 }
308
309 proof fn theorem_serialize_parse_roundtrip(&self, v: Self::Type) {
310 if self.wf(v) {
311 match v {
312 Some(vv) => {
313 assert(self.0.wf(vv));
314 self.0.lemma_serialize_productive(vv);
315 self.0.theorem_serialize_parse_roundtrip(vv);
316 },
317 None => {
318 // the following two lines establish a contradiction (n > 0 and n <= 0)
319 self.0.lemma_parse_productive(Seq::empty());
320 self.0.lemma_parse_length(Seq::empty());
321 },
322 }
323 }
324 }
325
326 proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
327 if let Some((n, v)) = self.0.spec_parse(buf) {
328 self.0.lemma_parse_productive(buf);
329 if n != 0 {
330 self.0.theorem_parse_serialize_roundtrip(buf);
331 }
332 } else {
333 assert(Seq::<u8>::empty() == buf.take(0));
334 }
335 }
336
337 proof fn lemma_parse_length(&self, s: Seq<u8>) {
338 if let Some((n, v)) = self.0.spec_parse(s) {
339 self.0.lemma_parse_length(s);
340 }
341 }
342
343 proof fn lemma_parse_productive(&self, s: Seq<u8>) {
344 }
345}
346
347impl<'x, I, O, T> Combinator<'x, I, O> for Opt<T> where
348 I: VestInput,
349 O: VestOutput<I>,
350 T: Combinator<'x, I, O, SType = &'x <T as Combinator<'x, I, O>>::Type>,
351 T::V: SecureSpecCombinator<Type = <T::Type as View>::V>,
352 T::Type: 'x,
353 {
354 type Type = Optional<T::Type>;
355
356 type SType = &'x Self::Type;
357
358 fn length(&self, v: Self::SType) -> usize {
359 assert(self@.wf(v@)); // TODO: why is this needed?
360 match &v.0 {
361 Some(v) => self.0.length(v),
362 None => 0,
363 }
364 }
365
366 open spec fn ex_requires(&self) -> bool {
367 self.0.ex_requires()
368 }
369
370 fn parse(&self, s: I) -> (res: Result<(usize, Self::Type), ParseError>) {
371 if let Ok((n, v)) = self.0.parse(s) {
372 Ok((n, Optional(Some(v))))
373 } else {
374 Ok((0, Optional(None)))
375 }
376 }
377
378 fn serialize(&self, v: Self::SType, data: &mut O, pos: usize) -> (res: Result<
379 usize,
380 SerializeError,
381 >) {
382 match &v.0 {
383 Some(v) => self.0.serialize(v, data, pos),
384 None => {
385 if pos <= data.len() {
386 assert(seq_splice(old(data)@, pos, Seq::<u8>::empty()) == data@);
387 Ok(0)
388 } else {
389 Err(SerializeError::InsufficientBuffer)
390 }
391 },
392 }
393 }
394}
395
396pub struct OptThen<Fst, Snd>(pub (Opt<Fst>, Snd));
397
398impl<Fst: View, Snd: View> View for OptThen<Fst, Snd> {
399 type V = OptThen<Fst::V, Snd::V>;
400
401 open spec fn view(&self) -> Self::V {
402 OptThen((self.0.0@, self.0.1@))
403 }
404}
405
406impl<Fst, Snd> OptThen<Fst, Snd> where
407 {
408 pub open spec fn spec_new(fst: Fst, snd: Snd) -> Self {
409 OptThen((Opt(fst), snd))
410 }
411
412 pub fn new(fst: Fst, snd: Snd) -> (o: Self)
413 ensures
414 o == OptThen((Opt(fst), snd)),
415 {
416 OptThen((Opt(fst), snd))
417 }
418}
419
420impl<C, Fst, Snd> DisjointFrom<C> for OptThen<Fst, Snd> where
421 C: SpecCombinator,
422 Fst: SecureSpecCombinator + DisjointFrom<C>,
423 Snd: SpecCombinator + DisjointFrom<Fst> + DisjointFrom<C>,
424 {
425 open spec fn disjoint_from(&self, other: &C) -> bool {
426 &&& self.0.0.0.disjoint_from(other)
427 &&& self.0.1.disjoint_from(other)
428 }
429
430 proof fn parse_disjoint_on(&self, other: &C, buf: Seq<u8>) {
431 match self.spec_parse(buf) {
432 Some((_, (Some(_), _))) => {
433 self.0.0.0.parse_disjoint_on(other, buf);
434 self.0.1.parse_disjoint_on(other, buf);
435 },
436 Some((_, (None, _))) => {
437 assert(buf.skip(0) == buf);
438 self.0.1.parse_disjoint_on(other, buf);
439 },
440 _ => {}
441 }
442 }
443}
444
445
446impl<Fst, Snd> SpecCombinator for OptThen<Fst, Snd> where
447 Fst: SecureSpecCombinator,
448 Snd: SpecCombinator + DisjointFrom<Fst>,
449 {
450 type Type = (<Opt<Fst> as SpecCombinator>::Type, Snd::Type);
451
452 open spec fn requires(&self) -> bool {
453 // instead of just requiring `Fst` to be
454 // prefix-secure, we require `Snd`
455 // to be disjoint from `Fst`
456 // Note that `Opt<T>` is always not prefix-secure
457 Fst::is_prefix_secure()
458 && self.0.0.requires() && self.0.1.requires()
459 && self.0.1.disjoint_from(&self.0.0.0)
460 }
461
462 open spec fn wf(&self, v: Self::Type) -> bool {
463 self.0.wf(v)
464 }
465
466 open spec fn spec_parse(&self, s: Seq<u8>) -> Option<(int, Self::Type)> {
467 self.0.spec_parse(s)
468 }
469
470 open spec fn spec_serialize(&self, v: Self::Type) -> Seq<u8> {
471 self.0.spec_serialize(v)
472 }
473}
474
475impl<Fst, Snd> SecureSpecCombinator for OptThen<Fst, Snd> where
476 Fst: SecureSpecCombinator,
477 Snd: SecureSpecCombinator + DisjointFrom<Fst>,
478 {
479 proof fn theorem_serialize_parse_roundtrip(&self, v: Self::Type) {
480 let buf = self.spec_serialize(v);
481 let buf0 = self.0.0.spec_serialize(v.0);
482 let buf1 = self.0.1.spec_serialize(v.1);
483 self.0.0.theorem_serialize_parse_roundtrip(v.0);
484 self.0.1.theorem_serialize_parse_roundtrip(v.1);
485 assert((buf0 + buf1).skip(buf0.len() as int) == buf1);
486 self.0.0.0.lemma_prefix_secure(buf0, buf1);
487 self.0.1.parse_disjoint_on(&self.0.0.0, buf1); // <-- this is the key
488 }
489
490 proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
491 if let Some((nm, (v0, v1))) = self.spec_parse(buf) {
492 let (n, v0_) = self.0.0.spec_parse(buf).unwrap();
493 self.0.0.lemma_parse_length(buf);
494 let buf0 = buf.take(n);
495 let buf1 = buf.skip(n);
496 assert(buf == buf0 + buf1);
497 self.0.0.theorem_parse_serialize_roundtrip(buf);
498 let (m, v1_) = self.0.1.spec_parse(buf1).unwrap();
499 self.0.1.theorem_parse_serialize_roundtrip(buf1);
500 self.0.1.lemma_parse_length(buf1);
501 let buf2 = self.spec_serialize((v0, v1));
502 assert(buf2 == buf.take(nm));
503 }
504 }
505
506 open spec fn is_prefix_secure() -> bool {
507 Fst::is_prefix_secure() && Snd::is_prefix_secure()
508 }
509
510 proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
511 if Fst::is_prefix_secure() && Snd::is_prefix_secure() {
512 self.0.0.0.lemma_prefix_secure(s1, s2);
513 self.0.0.lemma_parse_length(s1);
514 if let Some((n1, v1)) = self.0.0.spec_parse(s1) {
515 match v1 {
516 Some(v1) => {
517 assert(s1.skip(n1) + s2 == (s1 + s2).skip(n1));
518 self.0.1.lemma_prefix_secure(s1.skip(n1), s2);
519 },
520 None => {
521 assert(s1.skip(n1) == s1);
522 assert(self.0.0.0.spec_parse(s1) is None);
523 self.0.1.lemma_prefix_secure(s1, s2);
524 if let Some((n2, v2)) = self.0.1.spec_parse(s1) {
525 self.0.1.parse_disjoint_on(&self.0.0.0, s1 + s2);
526 assert(self.0.0.0.spec_parse(s1 + s2) is None);
527 }
528 },
529 }
530 }
531 }
532 }
533
534 proof fn lemma_parse_length(&self, s: Seq<u8>) {
535 if let Some((n, _)) = self.0.0.spec_parse(s) {
536 if let Some(_) = self.0.1.spec_parse(s.skip(n)) {
537 self.0.0.lemma_parse_length(s);
538 self.0.1.lemma_parse_length(s.skip(n));
539 }
540 }
541 }
542
543 open spec fn is_productive(&self) -> bool {
544 self.0.1.is_productive()
545 }
546
547 proof fn lemma_parse_productive(&self, s: Seq<u8>) {
548 if let Some((n, _)) = self.0.0.spec_parse(s) {
549 if let Some(_) = self.0.1.spec_parse(s.skip(n)) {
550 self.0.0.0.lemma_parse_length(s);
551 self.0.1.lemma_parse_productive(s.skip(n));
552 self.0.1.lemma_parse_length(s.skip(n));
553 }
554 }
555 }
556}
557
558impl<'x, I, O, Fst, Snd> Combinator<'x, I, O> for OptThen<Fst, Snd> where
559 I: VestInput,
560 O: VestOutput<I>,
561 Fst: Combinator<'x, I, O, SType = &'x <Fst as Combinator<'x, I, O>>::Type>,
562 Snd: Combinator<'x, I, O>,
563 Fst::V: SecureSpecCombinator<Type = <Fst::Type as View>::V>,
564 Snd::V: SecureSpecCombinator<Type = <Snd::Type as View>::V>,
565 Snd::V: DisjointFrom<Fst::V>,
566 Fst::Type: 'x,
567 {
568 type Type = (<Opt<Fst> as Combinator<'x, I, O>>::Type, Snd::Type);
569
570 type SType = (<Opt<Fst> as Combinator<'x, I, O>>::SType, Snd::SType);
571
572 fn length(&self, v: Self::SType) -> usize {
573 self.0.0.length(&v.0) + self.0.1.length(v.1)
574 }
575
576 open spec fn ex_requires(&self) -> bool {
577 self.0.ex_requires()
578 }
579
580 fn parse(&self, s: I) -> (res: Result<(usize, Self::Type), ParseError>) {
581 let (n, v1) = self.0.0.parse(s.clone())?;
582 proof {
583 self@.0.0.lemma_parse_length(s@);
584 }
585 let s_ = s.subrange(n, s.len());
586 let (m, v2) = self.0.1.parse(s_)?;
587 proof {
588 self.0.1@.lemma_parse_length(s@.skip(n as int));
589 }
590 Ok((n + m, (v1, v2)))
591 }
592
593 fn serialize(&self, v: Self::SType, data: &mut O, pos: usize) -> (res: Result<
594 usize,
595 SerializeError,
596 >) {
597 let n = self.0.0.serialize(&v.0, data, pos)?;
598 let m = self.0.1.serialize(v.1, data, pos + n)?;
599 Ok(n + m)
600 }
601}
602
603/// This macro constructs a nested OrdChoice combinator
604/// in the form of OrdChoice(..., OrdChoice(..., OrdChoice(..., ...)))
605#[allow(unused_macros)]
606#[macro_export]
607macro_rules! ord_choice {
608 ($c:expr $(,)?) => {
609 $c
610 };
611
612 ($c:expr, $($rest:expr),* $(,)?) => {
613 Choice($c, ord_choice!($($rest),*))
614 };
615}
616
617pub use ord_choice;
618
619/// Build a type for the `ord_choice!` macro
620#[allow(unused_macros)]
621#[macro_export]
622macro_rules! ord_choice_type {
623 ($c:ty $(,)?) => {
624 $c
625 };
626
627 ($c:ty, $($rest:ty),* $(,)?) => {
628 OrdChoice<$c, ord_choice_type!($($rest),*)>
629 };
630}
631
632pub use ord_choice_type;
633
634/// Build a type for the result of `ord_choice!`
635#[allow(unused_macros)]
636#[macro_export]
637macro_rules! ord_choice_result {
638 ($c:ty $(,)?) => {
639 $c
640 };
641
642 ($c:ty, $($rest:ty),* $(,)?) => {
643 Either<$c, ord_choice_result!($($rest),*)>
644 };
645}
646
647pub use ord_choice_result;
648
649/// Maps x:Ti to ord_choice_result!(T1, ..., Tn)
650#[allow(unused_macros)]
651#[macro_export]
652macro_rules! inj_ord_choice_result {
653 (*, $($rest:tt),* $(,)?) => {
654 Either::Right(inj_ord_choice_result!($($rest),*))
655 };
656
657 ($x:expr $(,)?) => {
658 $x
659 };
660
661 ($x:expr, $(*),* $(,)?) => {
662 Either::Left($x)
663 };
664}
665
666pub use inj_ord_choice_result;
667
668/// Same as above but for patterns
669#[allow(unused_macros)]
670#[macro_export]
671macro_rules! inj_ord_choice_pat {
672 (*, $($rest:tt),* $(,)?) => {
673 Either::Right(inj_ord_choice_pat!($($rest),*))
674 };
675
676 ($x:pat $(,)?) => {
677 $x
678 };
679
680 ($x:pat, $(*),* $(,)?) => {
681 Either::Left($x)
682 };
683}
684
685pub use inj_ord_choice_pat;
686
687// what would it look like if we manually implemented the match combinator?
688//
689// use super::uints::*;
690// use super::tail::*;
691//
692// pub struct MatchU8With123 {
693// pub val: u8,
694// pub arm1: U8,
695// pub arm2: U16,
696// pub arm3: U32,
697// pub default: Tail,
698// }
699//
700// impl View for MatchU8With123 {
701// type V = Self;
702//
703// open spec fn view(&self) -> Self::V {
704// MatchU8With123 {
705// val: self.val,
706// arm1: self.arm1@,
707// arm2: self.arm2@,
708// arm3: self.arm3@,
709// default: self.default@,
710// }
711// }
712// }
713//
714// pub enum SpecMsgMatchU8With123 {
715// Arm1(u8),
716// Arm2(u16),
717// Arm3(u32),
718// Default(Seq<u8>),
719// }
720//
721// pub enum MsgMatchU8With123<'a> {
722// Arm1(u8),
723// Arm2(u16),
724// Arm3(u32),
725// Default(&'a [u8]),
726// }
727//
728// pub enum MsgMatchU8With123 {
729// Arm1(u8),
730// Arm2(u16),
731// Arm3(u32),
732// Default(Vec<u8>),
733// }
734//
735// impl View for MsgMatchU8With123<'_> {
736// type V = SpecMsgMatchU8With123;
737//
738// open spec fn view(&self) -> Self::V {
739// match self {
740// MsgMatchU8With123::Arm1(v) => SpecMsgMatchU8With123::Arm1(v@),
741// MsgMatchU8With123::Arm2(v) => SpecMsgMatchU8With123::Arm2(v@),
742// MsgMatchU8With123::Arm3(v) => SpecMsgMatchU8With123::Arm3(v@),
743// MsgMatchU8With123::Default(v) => SpecMsgMatchU8With123::Default(v@),
744// }
745// }
746// }
747//
748// impl View for MsgMatchU8With123 {
749// type V = SpecMsgMatchU8With123;
750//
751// open spec fn view(&self) -> Self::V {
752// match self {
753// MsgMatchU8With123::Arm1(v) => SpecMsgMatchU8With123::Arm1(v@),
754// MsgMatchU8With123::Arm2(v) => SpecMsgMatchU8With123::Arm2(v@),
755// MsgMatchU8With123::Arm3(v) => SpecMsgMatchU8With123::Arm3(v@),
756// MsgMatchU8With123::Default(v) => SpecMsgMatchU8With123::Default(v@),
757// }
758// }
759// }
760//
761// impl SpecCombinator for MatchU8With123 {
762// type SpecResult = SpecMsgMatchU8With123;
763//
764// open spec fn spec_parse(&self, s: Seq<u8>) -> Result<(usize, Self::SpecResult), ()> {
765// match self.val {
766// 1u8 => {
767// if let Ok((n, v)) = self.arm1.spec_parse(s) {
768// Ok((n, SpecMsgMatchU8With123::Arm1(v)))
769// } else {
770// Err(())
771// }
772// },
773// 2u8 => {
774// if let Ok((n, v)) = self.arm2.spec_parse(s) {
775// Ok((n, SpecMsgMatchU8With123::Arm2(v)))
776// } else {
777// Err(())
778// }
779// },
780// 3u8 => {
781// if let Ok((n, v)) = self.arm3.spec_parse(s) {
782// Ok((n, SpecMsgMatchU8With123::Arm3(v)))
783// } else {
784// Err(())
785// }
786// },
787// _ => {
788// if let Ok((n, v)) = self.default.spec_parse(s) {
789// Ok((n, SpecMsgMatchU8With123::Default(v)))
790// } else {
791// Err(())
792// }
793// },
794// }
795// }
796//
797// proof fn spec_parse_wf(&self, s: Seq<u8>) {
798// match self.val {
799// 1u8 => {
800// if let Ok((n, v)) = self.arm1.spec_parse(s) {
801// self.arm1.spec_parse_wf(s);
802// }
803// },
804// 2u8 => {
805// if let Ok((n, v)) = self.arm2.spec_parse(s) {
806// self.arm2.spec_parse_wf(s);
807// }
808// },
809// 3u8 => {
810// if let Ok((n, v)) = self.arm3.spec_parse(s) {
811// self.arm3.spec_parse_wf(s);
812// }
813// },
814// _ => {
815// if let Ok((n, v)) = self.default.spec_parse(s) {
816// self.default.spec_parse_wf(s);
817// }
818// },
819// }
820// }
821//
822// open spec fn spec_serialize(&self, v: Self::SpecResult) -> Result<Seq<u8>, ()> {
823// match self.val {
824// 1u8 => {
825// if let SpecMsgMatchU8With123::Arm1(v) = v {
826// self.arm1.spec_serialize(v)
827// } else {
828// Err(())
829// }
830// },
831// 2u8 => {
832// if let SpecMsgMatchU8With123::Arm2(v) = v {
833// self.arm2.spec_serialize(v)
834// } else {
835// Err(())
836// }
837// },
838// 3u8 => {
839// if let SpecMsgMatchU8With123::Arm3(v) = v {
840// self.arm3.spec_serialize(v)
841// } else {
842// Err(())
843// }
844// },
845// _ => {
846// if let SpecMsgMatchU8With123::Default(v) = v {
847// self.default.spec_serialize(v)
848// } else {
849// Err(())
850// }
851// },
852// }
853// }
854// }
855//
856// impl SecureSpecCombinator for MatchU8With123 {
857// open spec fn spec_is_prefix_secure() -> bool {
858// U8::spec_is_prefix_secure() && U16::spec_is_prefix_secure() && U32::spec_is_prefix_secure()
859// && Tail::spec_is_prefix_secure()
860// }
861//
862// proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
863// match self.val {
864// 1u8 => {
865// self.arm1.lemma_prefix_secure(s1, s2);
866// },
867// 2u8 => {
868// self.arm2.lemma_prefix_secure(s1, s2);
869// },
870// 3u8 => {
871// self.arm3.lemma_prefix_secure(s1, s2);
872// },
873// _ => {
874// self.default.lemma_prefix_secure(s1, s2);
875// },
876// }
877// }
878//
879// proof fn theorem_serialize_parse_roundtrip(&self, v: Self::SpecResult) {
880// match self.val {
881// 1u8 => {
882// if let SpecMsgMatchU8With123::Arm1(v) = v {
883// self.arm1.theorem_serialize_parse_roundtrip(v);
884// }
885// },
886// 2u8 => {
887// if let SpecMsgMatchU8With123::Arm2(v) = v {
888// self.arm2.theorem_serialize_parse_roundtrip(v);
889// }
890// },
891// 3u8 => {
892// if let SpecMsgMatchU8With123::Arm3(v) = v {
893// self.arm3.theorem_serialize_parse_roundtrip(v);
894// }
895// },
896// _ => {
897// if let SpecMsgMatchU8With123::Default(v) = v {
898// self.default.theorem_serialize_parse_roundtrip(v);
899// }
900// },
901// }
902// }
903//
904// proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
905// match self.val {
906// 1u8 => {
907// self.arm1.theorem_parse_serialize_roundtrip(buf);
908// },
909// 2u8 => {
910// self.arm2.theorem_parse_serialize_roundtrip(buf);
911// },
912// 3u8 => {
913// self.arm3.theorem_parse_serialize_roundtrip(buf);
914// },
915// _ => {
916// self.default.theorem_parse_serialize_roundtrip(buf);
917// },
918// }
919// }
920// }
921//
922// impl Combinator for MatchU8With123 {
923// type Result<'a> = MsgMatchU8With123<'a>;
924//
925// type = MsgMatchU8With123;
926//
927// open spec fn spec_length(&self) -> Option<usize> {
928// None
929// }
930//
931// fn length(&self) -> Option<usize> {
932// None
933// }
934//
935// fn exec_is_prefix_secure() -> bool {
936// U8::exec_is_prefix_secure() && U16::exec_is_prefix_secure() && U32::exec_is_prefix_secure()
937// && Tail::exec_is_prefix_secure()
938// }
939//
940// open spec fn parse_requires(&self) -> bool {
941// self.arm1.parse_requires() && self.arm2.parse_requires() && self.arm3.parse_requires()
942// && self.default.parse_requires()
943// }
944//
945// fn parse<'a>(&self, s: &'a [u8]) -> (res: Result<(usize, Self::Result<'a>), ()>) {
946// match self.val {
947// 1u8 => {
948// if let Ok((n, v)) = self.arm1.parse(s) {
949// Ok((n, MsgMatchU8With123::Arm1(v)))
950// } else {
951// Err(())
952// }
953// },
954// 2u8 => {
955// if let Ok((n, v)) = self.arm2.parse(s) {
956// Ok((n, MsgMatchU8With123::Arm2(v)))
957// } else {
958// Err(())
959// }
960// },
961// 3u8 => {
962// if let Ok((n, v)) = self.arm3.parse(s) {
963// Ok((n, MsgMatchU8With123::Arm3(v)))
964// } else {
965// Err(())
966// }
967// },
968// _ => {
969// if let Ok((n, v)) = self.default.parse(s) {
970// Ok((n, MsgMatchU8With123::Default(v)))
971// } else {
972// Err(())
973// }
974// },
975// }
976// }
977//
978// open spec fn serialize_requires(&self) -> bool {
979// self.arm1.serialize_requires() && self.arm2.serialize_requires()
980// && self.arm3.serialize_requires() && self.default.serialize_requires()
981// }
982//
983// fn serialize(&self, v: Self::Result<'_>, data: &mut Vec<u8>, pos: usize) -> (res: Result<
984// usize,
985// (),
986// >) {
987// match self.val {
988// 1u8 => {
989// if let MsgMatchU8With123::Arm1(v) = v {
990// self.arm1.serialize(v, data, pos)
991// } else {
992// Err(())
993// }
994// },
995// 2u8 => {
996// if let MsgMatchU8With123::Arm2(v) = v {
997// self.arm2.serialize(v, data, pos)
998// } else {
999// Err(())
1000// }
1001// },
1002// 3u8 => {
1003// if let MsgMatchU8With123::Arm3(v) = v {
1004// self.arm3.serialize(v, data, pos)
1005// } else {
1006// Err(())
1007// }
1008// },
1009// _ => {
1010// if let MsgMatchU8With123::Default(v) = v {
1011// self.default.serialize(v, data, pos)
1012// } else {
1013// Err(())
1014// }
1015// },
1016// }
1017// }
1018// }
1019} // verus!