essential_vm/
op_access.rs

1//! The `OpAccess` trait declaration and its implementations.
2
3use crate::{asm::TryFromBytes, bytecode::BytecodeMapped};
4use std::sync::Arc;
5
6/// Types that provide access to operations.
7///
8/// Implementations are included for `&[Op]`, [`BytecodeMapped`] and `Arc<T>`.
9pub trait OpAccess: Clone + Send + Sync {
10    /// The operation type being accessed.
11    type Op;
12    /// Any error that might occur during access.
13    type Error: core::fmt::Debug + core::fmt::Display + Send;
14    /// Access the operation at the given index.
15    ///
16    /// Mutable access to self is required in case operations are lazily parsed.
17    ///
18    /// Any implementation should ensure the same index always returns the same operation.
19    fn op_access(&self, index: usize) -> Option<Result<Self::Op, Self::Error>>;
20}
21
22impl<Op> OpAccess for &[Op]
23where
24    Op: Clone + Send + Sync,
25{
26    type Op = Op;
27    type Error = core::convert::Infallible;
28    fn op_access(&self, index: usize) -> Option<Result<Self::Op, Self::Error>> {
29        self.get(index).cloned().map(Ok)
30    }
31}
32
33impl<Op, Bytes> OpAccess for &BytecodeMapped<Op, Bytes>
34where
35    Op: TryFromBytes + Send + Sync,
36    Bytes: core::ops::Deref<Target = [u8]> + Send + Sync,
37{
38    type Op = Op;
39    type Error = core::convert::Infallible;
40    fn op_access(&self, index: usize) -> Option<Result<Self::Op, Self::Error>> {
41        self.op(index).map(Ok)
42    }
43}
44
45impl<T> OpAccess for Arc<T>
46where
47    T: OpAccess,
48{
49    type Op = T::Op;
50    type Error = T::Error;
51    fn op_access(&self, index: usize) -> Option<Result<Self::Op, Self::Error>> {
52        (**self).op_access(index)
53    }
54}