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(test)]
49mod tests {
50    use super::*;
51    use crate::*;
52
53    impl VmStore {
54        pub fn new_packed() -> Self {
55            Self {
56                inner: vec![
57                    VmStackValue::from(PQLStreet::default()).into();
58                    u8::MAX as usize + 1
59                ],
60            }
61        }
62    }
63
64    #[test]
65    fn test_try_push() {
66        assert!(matches!(
67            VmStore::new_packed().try_push(VmValue::Str(String::new())),
68            Err(PQLError::TooManyVariables)
69        ));
70    }
71
72    #[test]
73    fn test_downcast_get() {
74        let mut i = PQLLong::default();
75        let v: VmValue = VmStackValue::from(i).into();
76        let mut store = VmStore::default();
77        let idx = store.try_push(v).unwrap();
78
79        assert_eq!(&i, store.downcast_get::<&PQLLong>(idx).unwrap());
80        assert_eq!(
81            &mut i,
82            store.downcast_get_mut::<&mut PQLLong>(idx).unwrap()
83        );
84
85        assert!(store.downcast_get::<&PQLString>(idx).is_err());
86        assert!(store.downcast_get_mut::<&mut PQLString>(idx).is_err());
87    }
88}