open_pql/vm/
store.rs

1use super::*;
2
3#[derive(Debug, Clone, Default)]
4pub struct VmStore {
5    pub(crate) inner: Vec<VmValue>,
6}
7
8impl VmStore {
9    pub fn try_push(&mut self, v: VmValue) -> Result<VmStoreVarIdx, PQLError> {
10        let idx = self.inner.len().try_into()?;
11
12        self.inner.push(v);
13
14        Ok(idx)
15    }
16
17    fn get(&self, i: VmStoreVarIdx) -> &VmValue {
18        &self.inner[i.to_usize()]
19    }
20
21    fn get_mut(&mut self, i: VmStoreVarIdx) -> &mut VmValue {
22        &mut self.inner[i.to_usize()]
23    }
24
25    pub fn downcast_get<'a, T>(
26        &'a self,
27        i: VmStoreVarIdx,
28    ) -> Result<T, PQLError>
29    where
30        T: TryFrom<&'a VmValue>,
31    {
32        T::try_from(self.get(i))
33            .map_or_else(|_| Err(InternalError::InvalidVmValue.into()), Ok)
34    }
35
36    pub fn downcast_get_mut<'a, T>(
37        &'a mut self,
38        i: VmStoreVarIdx,
39    ) -> Result<T, PQLError>
40    where
41        T: TryFrom<&'a mut VmValue>,
42    {
43        T::try_from(self.get_mut(i))
44            .map_or_else(|_| Err(InternalError::InvalidVmValue.into()), Ok)
45    }
46}
47
48#[cfg_attr(coverage_nightly, coverage(off))]
49#[cfg(test)]
50mod tests {
51    use super::*;
52    use crate::*;
53
54    impl VmStore {
55        pub fn new_packed() -> Self {
56            Self {
57                inner: vec![
58                    VmStackValue::from(PQLStreet::default()).into();
59                    u8::MAX as usize + 1
60                ],
61            }
62        }
63    }
64
65    #[test]
66    fn test_try_push() {
67        assert!(matches!(
68            VmStore::new_packed().try_push(VmValue::Str(String::new())),
69            Err(PQLError::TooManyVariables)
70        ));
71    }
72
73    #[test]
74    fn test_downcast_get() {
75        let mut i = PQLLong::default();
76        let v: VmValue = VmStackValue::from(i).into();
77        let mut store = VmStore::default();
78        let idx = store.try_push(v).unwrap();
79
80        assert_eq!(&i, store.downcast_get::<&PQLLong>(idx).unwrap());
81        assert_eq!(
82            &mut i,
83            store.downcast_get_mut::<&mut PQLLong>(idx).unwrap()
84        );
85
86        assert!(store.downcast_get::<&PQLString>(idx).is_err());
87        assert!(store.downcast_get_mut::<&mut PQLString>(idx).is_err());
88    }
89}