vest_lib 0.2.2

Verified parser and serializer combinators in Verus
Documentation
//! Executable implementations for optional formats.
use crate::core::exec::output::*;
use crate::core::{
    exec::{
        input::InputBuf,
        parser::{PResult, Parser},
        serializer::{ByteLen, PreSerializeError, Prepare, Serializer},
    },
    spec::{SafeParser, SpecParser},
};
use vstd::prelude::*;
use OutputBuf;

verus! {

impl<I, A> Parser<I> for super::Opt<A> where I: View<V = Seq<u8>>, A: Parser<I> {
    type PT = Option<A::PT>;

    fn min_byte_len(&self) -> usize {
        0
    }

    open spec fn exec_inv(&self) -> bool {
        self.0.exec_inv()
    }

    fn parse(&self, ibuf: &I) -> PResult<Self::PT> {
        match self.0.parse(ibuf) {
            Ok((n, v)) => Ok((n, Some(v))),
            Err(_) => {
                let none = None;
                assert(self.spec_parse(ibuf@) == Some((0int, none.deep_view())));
                Ok((0, none))
            },
        }
    }
}

impl<Output: OutputBuf, A, T> Serializer<Output, Option<T>> for super::Opt<A> where
    T: DeepView,
    A: Serializer<Output, T>,
 {
    #[verifier::prophetic]
    open spec fn exec_inv(&self) -> bool {
        self.0.exec_inv()
    }

    fn serialize_into(&self, v: &Option<T>, obuf: &mut Output) {
        broadcast use crate::core::exec::output::outbuf_lemmas;

        match v {
            Some(vv) => self.0.serialize_into(vv, obuf),
            None => {},
        }
    }
}

impl<A, T> ByteLen<Option<T>> for super::Opt<A> where T: DeepView, A: ByteLen<T> {
    open spec fn exec_inv(&self) -> bool {
        self.0.exec_inv()
    }

    fn length(&self, v: &Option<T>) -> (len: usize) {
        match v {
            Some(vv) => self.0.length(vv),
            None => 0,
        }
    }
}

impl<A, T> Prepare<Option<T>> for super::Opt<A> where T: DeepView, A: Prepare<T> {
    open spec fn exec_inv(&self) -> bool {
        self.0.exec_inv()
    }

    fn prepare(&self, v: &Option<T>) -> (checked: Result<usize, PreSerializeError>) {
        match v {
            Some(vv) => self.0.prepare(vv),
            None => Ok(0),
        }
    }
}

impl<I, A, B> Parser<I> for super::Optional<A, B> where
    I: InputBuf,
    A: Parser<I> + SafeParser,
    B: Parser<I> + SafeParser,
 {
    type PT = (Option<A::PT>, B::PT);

    fn min_byte_len(&self) -> usize {
        // The optional half may be absent, so only `B` is guaranteed.
        self.1.min_byte_len()
    }

    open spec fn exec_inv(&self) -> bool {
        &&& self.0.exec_inv()
        &&& self.0.safe_inv()
        &&& self.1.exec_inv()
        &&& self.1.safe_inv()
    }

    fn parse(&self, ibuf: &I) -> PResult<Self::PT> {
        crate::combinators::Pair(super::Opt(&self.0), &self.1).parse(ibuf)
    }
}

impl<Output: OutputBuf, A, B, TA, TB> Serializer<Output, (Option<TA>, TB)> for super::Optional<
    A,
    B,
> where TA: DeepView, TB: DeepView, A: Serializer<Output, TA>, B: Serializer<Output, TB> {
    #[verifier::prophetic]
    open spec fn exec_inv(&self) -> bool {
        &&& self.0.exec_inv()
        &&& self.1.exec_inv()
    }

    fn serialize_into(&self, v: &(Option<TA>, TB), obuf: &mut Output) {
        crate::combinators::Pair(super::Opt(&self.0), &self.1).serialize_into(v, obuf);
    }
}

impl<A, B, TA, TB> ByteLen<(Option<TA>, TB)> for super::Optional<A, B> where
    TA: DeepView,
    TB: DeepView,
    A: ByteLen<TA>,
    B: ByteLen<TB>,
 {
    open spec fn exec_inv(&self) -> bool {
        &&& self.0.exec_inv()
        &&& self.1.exec_inv()
    }

    fn length(&self, v: &(Option<TA>, TB)) -> (len: usize) {
        crate::combinators::Pair(super::Opt(&self.0), &self.1).length(v)
    }
}

impl<A, B, TA, TB> Prepare<(Option<TA>, TB)> for super::Optional<A, B> where
    TA: DeepView,
    TB: DeepView,
    A: Prepare<TA>,
    B: Prepare<TB>,
 {
    open spec fn exec_inv(&self) -> bool {
        &&& self.0.exec_inv()
        &&& self.1.exec_inv()
    }

    fn prepare(&self, v: &(Option<TA>, TB)) -> Result<usize, PreSerializeError> {
        crate::combinators::Pair(super::Opt(&self.0), &self.1).prepare(v)
    }
}

} // verus!