spore_vm/val/
protected_val.rs1use std::ops::Deref;
2
3#[allow(unused_imports)]
4use log::*;
5
6use crate::Vm;
7
8use super::{
9 custom::{CustomValError, CustomValMut, CustomValRef},
10 CustomType, Val,
11};
12
13#[derive(Debug)]
17pub struct ProtectedVal<'a> {
18 pub(crate) vm: &'a mut Vm,
19 pub(crate) val: Val<'a>,
20}
21
22impl<'a> ProtectedVal<'a> {
23 pub fn new(vm: &'a mut Vm, v: Val<'a>) -> ProtectedVal<'a> {
28 vm.objects.keep_reachable(v.inner);
29 ProtectedVal { vm, val: v }
30 }
31
32 pub fn split(&mut self) -> (&mut Vm, &Val) {
36 (self.vm, &self.val)
37 }
38
39 pub fn with<T>(&mut self, f: impl Fn(&mut Vm, &Val) -> T) -> T {
42 let (vm, val) = self.split();
43 f(vm, val)
44 }
45}
46
47impl<'a> Drop for ProtectedVal<'a> {
48 fn drop(&mut self) {
49 self.vm.objects.allow_unreachable(self.val.inner);
50 }
51}
52
53impl<'a> Deref for ProtectedVal<'a> {
54 type Target = Val<'a>;
55
56 fn deref(&self) -> &Self::Target {
57 &self.val
58 }
59}
60
61impl<'a> ProtectedVal<'a> {
62 pub fn vm(&self) -> &Vm {
64 self.vm
65 }
66
67 pub fn map<T>(&mut self, f: impl Fn(&mut Vm, &ProtectedVal<'a>) -> T) -> T {
70 let protected_val_ptr: *const ProtectedVal = self;
71 f(self.vm, unsafe { &*protected_val_ptr })
74 }
75
76 pub fn try_str(&'a self) -> Result<&'a str, Val> {
78 self.val.try_str(self.vm)
79 }
80
81 pub fn try_custom<T: CustomType>(&self) -> Result<CustomValRef<T>, CustomValError> {
84 self.val.try_custom(self.vm)
85 }
86
87 pub fn try_custom_mut<T: CustomType>(&self) -> Result<CustomValMut<T>, CustomValError> {
90 self.val.try_custom_mut(self.vm)
91 }
92
93 pub fn get_mutable_box_ref(&self) -> Result<Val, Val<'a>> {
96 self.val.try_mutable_box_ref(self.vm)
97 }
98}
99
100impl<'a> std::fmt::Display for ProtectedVal<'a> {
101 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
102 self.val.format_quoted(self.vm).fmt(f)
103 }
104}