verdict_parser/common/
wrapped.rs1use super::*;
2use std::marker::PhantomData;
3use vstd::prelude::*;
4
5verus! {
6
7pub type Wrapped<C> = Mapped<C, IdentityMapper<C>>;
11
12pub open spec fn spec_new_wrapped<C: Combinator>(c: C) -> Wrapped<C> where
13 C::V: SecureSpecCombinator<SpecResult = <C::Owned as View>::V>,
14{
15 Mapped {
16 inner: c,
17 mapper: IdentityMapper(PhantomData),
18 }
19}
20
21pub fn new_wrapped<C: Combinator>(c: C) -> Wrapped<C> where
22 C::V: SecureSpecCombinator<SpecResult = <C::Owned as View>::V>,
23{
24 Mapped {
25 inner: c,
26 mapper: IdentityMapper::new(),
27 }
28}
29
30#[derive(Debug)]
34pub struct IdentityMapper<C>(pub PhantomData<C>);
35
36impl<C: View> View for IdentityMapper<C> {
37 type V = IdentityMapper<C::V>;
38
39 open spec fn view(&self) -> Self::V {
40 IdentityMapper(PhantomData)
41 }
42}
43
44impl<C> IdentityMapper<C> {
45 pub fn new() -> Self {
46 IdentityMapper(PhantomData)
47 }
48}
49
50impl<C: SpecCombinator> SpecIso for IdentityMapper<C> {
51 type Src = C::SpecResult;
52 type Dst = C::SpecResult;
53
54 proof fn spec_iso(s: Self::Src) {}
55 proof fn spec_iso_rev(s: Self::Dst) {}
56}
57
58impl<C: Combinator> Iso for IdentityMapper<C> where
59 C::V: SecureSpecCombinator<SpecResult = <C::Owned as View>::V>,
60{
61 type Src<'a> = C::Result<'a>;
62 type Dst<'a> = C::Result<'a>;
63
64 type SrcOwned = C::Owned;
65 type DstOwned = C::Owned;
66}
67
68#[allow(unused_macros)]
85macro_rules! wrap_combinator {
86 ($vis:vis struct $name:ident $({ $($field_vis:vis $field_name:ident: $field_type:ty),* $(,)? })?: $inner_type:ty = $inner_expr:expr ;) => {
88 wrap_combinator! {
89 $vis struct $name $({ $($field_vis $field_name: $field_type),* })?: $inner_type =>
90 spec <<$inner_type as View>::V as SpecCombinator>::SpecResult,
91 exec<'a> <$inner_type as Combinator>::Result<'a>,
92 owned <$inner_type as Combinator>::Owned,
93 = $inner_expr;
94 }
95 };
96
97 ($vis:vis struct $name:ident: $inner_type:ty =>
98 spec $spec_result:ty,
99 exec<$lt:lifetime> $result:ty,
100 owned $owned:ty $(,)?
101 = $inner_expr:expr ;) => {
102 ::builtin_macros::verus! {
103 #[derive(Debug, View)]
104 $vis struct $name;
105
106 wrap_combinator_impls! {
107 $vis struct $name {} : $inner_type =>
108 spec $spec_result,
109 exec<$lt> $result,
110 owned $owned
111 = $inner_expr;
112 }
113 }
114 };
115
116 ($vis:vis struct $name:ident { $($field_vis:vis $field_name:ident: $field_type:ty),* $(,)? } : $inner_type:ty =>
117 spec $spec_result:ty,
118 exec<$lt:lifetime> $result:ty,
119 owned $owned:ty $(,)?
120 = $inner_expr:expr ;) => {
121 ::builtin_macros::verus! {
122 #[derive(Debug, View)]
123 $vis struct $name { $($field_vis $field_name: $field_type),* }
124
125 wrap_combinator_impls! {
126 $vis struct $name { $($field_vis $field_name: $field_type),* } : $inner_type =>
127 spec $spec_result,
128 exec<$lt> $result,
129 owned $owned
130 = $inner_expr;
131 }
132 }
133 };
134}
135pub(crate) use wrap_combinator;
136
137#[allow(unused_macros)]
138macro_rules! wrap_combinator_impls {
139 ($vis:vis struct $name:ident { $($field_vis:vis $field_name:ident: $field_type:ty),* } : $inner_type:ty =>
140 spec $spec_result:ty,
141 exec<$lt:lifetime> $result:ty,
142 owned $owned:ty $(,)?
143 = $inner_expr:expr ;) => {
144 ::builtin_macros::verus! {
145 impl $name {
146 #[allow(dead_code)]
155 fn check_valid_inner_combinator() {
156 #[allow(unused_variables)]
158 let c: $inner_type = $inner_expr;
159
160 let ghost _ = $inner_expr.view();
162
163 let _ = $inner_expr.length();
165
166 assert(<<$inner_type as View>::V as SecureSpecCombinator>::is_prefix_secure());
168
169 assert(c.parse_requires());
171 assert(c.serialize_requires());
172 }
173 }
174
175 impl SpecCombinator for $name {
176 type SpecResult = $spec_result;
177
178 uninterp spec fn spec_parse(&self, s: Seq<u8>) -> Result<(usize, Self::SpecResult), ()>;
180
181 #[verifier::external_body]
183 proof fn spec_parse_wf(&self, s: Seq<u8>) {}
184
185 uninterp spec fn spec_serialize(&self, v: Self::SpecResult) -> Result<Seq<u8>, ()>;
187 }
188
189 impl SecureSpecCombinator for $name {
190 open spec fn is_prefix_secure() -> bool {
192 true }
194
195 #[verifier::external_body]
196 proof fn theorem_serialize_parse_roundtrip(&self, v: Self::SpecResult) {
197 }
199
200 #[verifier::external_body]
201 proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
202 }
204
205 #[verifier::external_body]
206 proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
207 }
209 }
210
211 impl Combinator for $name {
212 type Result<$lt> = $result;
213 type Owned = $owned;
214
215 uninterp spec fn spec_length(&self) -> Option<usize>;
216
217 #[verifier::external_body]
218 fn length(&self) -> Option<usize> {
219 $(let $field_name: $field_type = self.$field_name;)*
220 $inner_expr.length()
221 }
222
223 open spec fn parse_requires(&self) -> bool {
224 true }
226
227 #[verifier::external_body]
228 #[inline(always)]
229 #[allow(unexpected_cfgs)]
230 fn parse<'a>(&self, s: &'a [u8]) -> (res: Result<(usize, Self::Result<'a>), ParseError>) {
231 $(let $field_name: $field_type = self.$field_name;)*
232 let res = $inner_expr.parse(s);
233 #[cfg(feature = "trace")] {
234 use verdict_polyfill::*;
235 eprintln_join!("[", stringify!($name), "] ", format_dbg(&res));
236 }
237 res
238 }
239
240 open spec fn serialize_requires(&self) -> bool {
241 true }
243
244 #[verifier::external_body]
245 #[inline(always)]
246 fn serialize(&self, v: Self::Result<'_>, data: &mut Vec<u8>, pos: usize) -> (res: Result<usize, SerializeError>) {
247 $(let $field_name: $field_type = self.$field_name;)*
248 $inner_expr.serialize(v, data, pos)
249 }
250 }
251 }
252 };
253}
254pub(crate) use wrap_combinator_impls;
255
256}