verdict_parser/common/
cached.rs1use super::*;
2use std::ops::Deref;
3use vstd::prelude::*;
4
5verus! {
6
7#[derive(View)]
10pub struct Cached<T>(pub T);
11
12pub struct CachedValue<'a, C: Combinator> where
13 C::V: SecureSpecCombinator<SpecResult = <C::Owned as View>::V>,
14{
15 inner: C::Result<'a>,
16 combinator: Ghost<C>,
17 serialized: &'a [u8],
18}
19
20impl<'a, C: Combinator> View for CachedValue<'a, C> where
22 C::V: SecureSpecCombinator<SpecResult = <C::Owned as View>::V>,
23 for<'b> C::Result<'b>: View,
24{
25 type V = <C::Result<'a> as View>::V;
26
27 closed spec fn view(&self) -> Self::V {
28 self.inner@
29 }
30}
31
32impl<'a, C: Combinator> PolyfillClone for CachedValue<'a, C> where
33 C::V: SecureSpecCombinator<SpecResult = <C::Owned as View>::V>,
34 C::Result<'a>: PolyfillClone,
35{
36 #[inline(always)]
37 fn clone(&self) -> Self {
38 proof {
39 use_type_invariant(self);
40 }
41 CachedValue {
42 inner: self.inner.clone(),
43 combinator: self.combinator,
44 serialized: self.serialized,
45 }
46 }
47}
48
49impl<'a, C: Combinator> CachedValue<'a, C> where
50 C::V: SecureSpecCombinator<SpecResult = <C::Owned as View>::V>,
51{
52 #[verifier::type_invariant]
53 closed spec fn inv(self) -> bool {
54 let res = self.combinator@@.spec_serialize(self.inner@);
55 &&& res.is_ok()
56 &&& self.serialized@ =~= res.unwrap()
57 }
58
59 #[inline(always)]
60 pub fn get(&self) -> (res: &C::Result<'a>)
61 ensures res@ == self@
62 {
63 &self.inner
64 }
65
66 #[inline(always)]
73 pub fn serialize(&self) -> (res: &[u8])
74 requires forall |c1: C, c2: C| c1.view() == c2.view()
75 ensures forall |c: C| (#[trigger] c.view()).spec_serialize(self@) matches Ok(r) && r == res@
76 {
77 proof {
78 use_type_invariant(self);
79 }
80 self.serialized
81 }
82}
83
84impl<T: SpecCombinator> SpecCombinator for Cached<T> {
85 type SpecResult = T::SpecResult;
86
87 open spec fn spec_parse(&self, s: Seq<u8>) -> Result<(usize, Self::SpecResult), ()> {
88 self.0.spec_parse(s)
89 }
90
91 open spec fn spec_serialize(&self, v: Self::SpecResult) -> Result<Seq<u8>, ()> {
92 self.0.spec_serialize(v)
93 }
94
95 proof fn spec_parse_wf(&self, s: Seq<u8>) {
96 self.0.spec_parse_wf(s)
97 }
98}
99
100impl<T: SecureSpecCombinator> SecureSpecCombinator for Cached<T> {
101 open spec fn is_prefix_secure() -> bool {
102 T::is_prefix_secure()
103 }
104
105 proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
106 self.0.lemma_prefix_secure(s1, s2)
107 }
108
109 proof fn theorem_serialize_parse_roundtrip(&self, v: Self::SpecResult) {
110 self.0.theorem_serialize_parse_roundtrip(v)
111 }
112
113 proof fn theorem_parse_serialize_roundtrip(&self, s: Seq<u8>) {
114 self.0.theorem_parse_serialize_roundtrip(s)
115 }
116}
117
118impl<T: Combinator> Combinator for Cached<T> where
119 T::V: SecureSpecCombinator<SpecResult = <T::Owned as View>::V>,
120{
121 type Result<'a> = CachedValue<'a, T>;
122 type Owned = T::Owned;
123
124 open spec fn spec_length(&self) -> Option<usize> {
125 self.0.spec_length()
126 }
127
128 fn length(&self) -> Option<usize> {
129 self.0.length()
130 }
131
132 open spec fn parse_requires(&self) -> bool {
133 self.0.parse_requires()
134 }
135
136 #[inline(always)]
137 fn parse<'a>(&self, s: &'a [u8]) -> (res: Result<(usize, Self::Result<'a>), ParseError>)
138 {
139 let (n, x) = self.0.parse(s)?;
140 proof {
141 assert(s.len() <= usize::MAX);
142 self@.theorem_parse_serialize_roundtrip(s@);
143 }
144 Ok((n, CachedValue { inner: x, combinator: Ghost(self.0), serialized: slice_take(s, n) }))
145 }
146
147 open spec fn serialize_requires(&self) -> bool {
148 self.0.serialize_requires()
149 }
150
151 #[inline(always)]
152 fn serialize(&self, v: Self::Result<'_>, data: &mut Vec<u8>, pos: usize) -> (res: Result<
153 usize,
154 SerializeError,
155 >) {
156 self.0.serialize(v.inner, data, pos)
157 }
158}
159
160}
161
162impl<'a, C: Combinator> std::fmt::Debug for CachedValue<'a, C>
163where
164 C::V: SecureSpecCombinator<SpecResult = <C::Owned as View>::V>,
165 C::Result<'a>: std::fmt::Debug,
166{
167 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
168 self.inner.fmt(f)
169 }
170}