essential_constraint_vm/
op_access.rs

1//! The `OpAccess` trait declaration and its implementations.
2
3use crate::{
4    asm::{ToBytes, TryFromBytes},
5    BytecodeMapped, BytecodeMappedLazy,
6};
7
8/// Types that provide access to operations.
9///
10/// Implementations are included for `&[Op]`, [`BytecodeMapped`] and [`BytecodeMappedLazy`].
11pub trait OpAccess {
12    /// The operation type being accessed.
13    type Op;
14    /// Any error that might occur during access.
15    type Error: core::fmt::Debug + core::fmt::Display;
16    /// Access the operation at the given index.
17    ///
18    /// Mutable access to self is required in case operations are lazily parsed.
19    ///
20    /// Any implementation should ensure the same index always returns the same operation.
21    fn op_access(&mut self, index: usize) -> Option<Result<Self::Op, Self::Error>>;
22}
23
24impl<'a, Op> OpAccess for &'a [Op]
25where
26    Op: Clone,
27{
28    type Op = Op;
29    type Error = core::convert::Infallible;
30    fn op_access(&mut self, index: usize) -> Option<Result<Self::Op, Self::Error>> {
31        self.get(index).cloned().map(Ok)
32    }
33}
34
35impl<'a, Op, Bytes> OpAccess for &'a BytecodeMapped<Op, Bytes>
36where
37    Op: TryFromBytes,
38    Bytes: core::ops::Deref<Target = [u8]>,
39{
40    type Op = Op;
41    type Error = core::convert::Infallible;
42    fn op_access(&mut self, index: usize) -> Option<Result<Self::Op, Self::Error>> {
43        self.op(index).map(Ok)
44    }
45}
46
47impl<Op, I> OpAccess for BytecodeMappedLazy<Op, I>
48where
49    Op: ToBytes + TryFromBytes,
50    I: Iterator<Item = u8>,
51{
52    type Op = Op;
53    type Error = Op::Error;
54    fn op_access(&mut self, index: usize) -> Option<Result<Op, Self::Error>> {
55        loop {
56            match self.mapped.op(index) {
57                Some(op) => return Some(Ok(op)),
58                None => match Op::try_from_bytes(&mut self.iter)? {
59                    Err(err) => return Some(Err(err)),
60                    Ok(op) => self.mapped.push_op(op),
61                },
62            }
63        }
64    }
65}