sim_lib_standard_core/
guest_kit.rs1use std::{fmt, sync::Arc};
4
5use sim_kernel::{Cx, Result, Value};
6
7pub trait TruthPolicy: Send + Sync {
9 fn is_truthy(&self, cx: &mut Cx, value: &Value) -> Result<bool>;
11}
12
13pub trait CoercionPolicy: Send + Sync {
15 fn to_number(&self, cx: &mut Cx, value: &Value) -> Result<Option<Value>>;
17
18 fn to_string(&self, cx: &mut Cx, value: &Value) -> Result<Option<Value>>;
20}
21
22#[derive(Clone, Copy, Debug, PartialEq, Eq)]
24pub enum Arity {
25 Exact(usize),
27 AtLeastOne,
29 All,
31}
32
33pub fn adjust_values(mut values: Vec<Value>, rule: Arity, nil: Value) -> Vec<Value> {
35 match rule {
36 Arity::All => values,
37 Arity::AtLeastOne => {
38 if values.is_empty() {
39 vec![nil]
40 } else {
41 values.truncate(1);
42 values
43 }
44 }
45 Arity::Exact(count) => {
46 values.resize(count, nil);
47 values
48 }
49 }
50}
51
52#[derive(Clone)]
54pub struct GuestRuntimeKit {
55 pub truth: Arc<dyn TruthPolicy>,
57 pub coerce: Arc<dyn CoercionPolicy>,
59 pub nil: Value,
61}
62
63impl GuestRuntimeKit {
64 pub fn new(truth: Arc<dyn TruthPolicy>, coerce: Arc<dyn CoercionPolicy>, nil: Value) -> Self {
66 Self { truth, coerce, nil }
67 }
68
69 pub fn is_truthy(&self, cx: &mut Cx, value: &Value) -> Result<bool> {
71 self.truth.is_truthy(cx, value)
72 }
73
74 pub fn to_number(&self, cx: &mut Cx, value: &Value) -> Result<Option<Value>> {
76 self.coerce.to_number(cx, value)
77 }
78
79 pub fn to_string(&self, cx: &mut Cx, value: &Value) -> Result<Option<Value>> {
81 self.coerce.to_string(cx, value)
82 }
83
84 pub fn adjust_values(&self, values: Vec<Value>, rule: Arity) -> Vec<Value> {
86 adjust_values(values, rule, self.nil.clone())
87 }
88}
89
90impl fmt::Debug for GuestRuntimeKit {
91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 f.debug_struct("GuestRuntimeKit")
93 .field("nil", &self.nil)
94 .finish_non_exhaustive()
95 }
96}