Skip to main content

vest_lib/combinators/mapped/
mod.rs

1//! Semantic type transformations over structural combinator values.
2//!
3//! [`Mapped`] carries full round trips when its mapper is lossless and sound;
4//! [`TryMap`] also admits a fallible executable conversion.
5/// Executable trait implementations for this combinator.
6pub mod exec;
7/// Correctness proofs for this combinator.
8pub mod proof;
9/// Specification trait implementations for this combinator.
10pub mod spec;
11
12use vstd::prelude::*;
13
14verus! {
15
16/// `Mapped { inner, mapper }` transforms the inner combinator's value type.
17///
18/// Lossless mappers preserve all format properties including parser soundness and non-malleability, while lossy mappers may introduce malleability.
19#[derive(Copy)]
20pub struct Mapped<Inner, M> {
21    /// The inner combinator whose values are being transformed.
22    pub inner: Inner,
23    /// The mapping between the inner and outer value types.
24    pub mapper: M,
25}
26
27impl<Inner: Clone, M: Clone> Clone for Mapped<Inner, M> {
28    fn clone(&self) -> (cloned: Self)
29        ensures
30            call_ensures(Inner::clone, (&self.inner,), cloned.inner),
31            call_ensures(M::clone, (&self.mapper,), cloned.mapper),
32    {
33        Mapped { inner: self.inner.clone(), mapper: self.mapper.clone() }
34    }
35}
36
37/// `TryMap { inner, mapper }` is the derived combinator
38/// `Mapped { inner: Refined(inner, |v| mapper.wf_in(v)), mapper }`.
39///
40/// Parsing fails when the parsed inner value does not satisfy `mapper.wf_in`.
41/// Serialization maps values back with `mapper.spec_map_rev`, and consistency
42/// requires both `mapper.wf_out(v)` and that the reverse-mapped inner value is
43/// consistent and satisfies `mapper.wf_in`.
44#[derive(Copy)]
45pub struct TryMap<Inner, M> {
46    /// The inner combinator whose values are being transformed.
47    pub inner: Inner,
48    /// The mapping between the inner and outer value types.
49    pub mapper: M,
50}
51
52impl<Inner: Clone, M: Clone> Clone for TryMap<Inner, M> {
53    fn clone(&self) -> (cloned: Self)
54        ensures
55            call_ensures(Inner::clone, (&self.inner,), cloned.inner),
56            call_ensures(M::clone, (&self.mapper,), cloned.mapper),
57    {
58        TryMap { inner: self.inner.clone(), mapper: self.mapper.clone() }
59    }
60}
61
62} // verus!