diff --git a/languages/rust/oso/src/host/class.rs b/languages/rust/oso/src/host/class.rs index 3d60856cca..cc441df103 100644 --- a/languages/rust/oso/src/host/class.rs +++ b/languages/rust/oso/src/host/class.rs @@ -379,6 +379,10 @@ impl Instance { .unwrap_or_else(|_| self.debug_type_name) } + pub(crate) fn debug_name(&self) -> &'static str { + self.debug_type_name + } + /// Lookup an attribute on the instance via the registered `Class` pub fn get_attr(&self, name: &str, host: &mut Host) -> crate::Result { tracing::trace!({ method = %name }, "get_attr"); diff --git a/languages/rust/oso/src/host/from_polar.rs b/languages/rust/oso/src/host/from_polar.rs index 2b3caaf391..365f77417d 100644 --- a/languages/rust/oso/src/host/from_polar.rs +++ b/languages/rust/oso/src/host/from_polar.rs @@ -71,7 +71,11 @@ where if let PolarValue::Instance(instance) = val { Ok(instance.downcast::(None).map_err(|e| e.user())?.clone()) } else { - Err(TypeError::expected("Instance").user()) + Err( + TypeError::expected(format!("Instance of {}", std::any::type_name::())) + .got(val.type_name().to_string()) + .user(), + ) } } } diff --git a/languages/rust/oso/src/host/value.rs b/languages/rust/oso/src/host/value.rs index 487b8b2c1c..e4198cd713 100644 --- a/languages/rust/oso/src/host/value.rs +++ b/languages/rust/oso/src/host/value.rs @@ -127,4 +127,38 @@ This may mean you performed an operation in your policy over an unbound variable }; Term::new_from_ffi(value) } + + pub fn type_name(&self) -> PolarValueType { + match self { + PolarValue::Integer(_) => PolarValueType::Integer, + PolarValue::Float(_) => PolarValueType::Float, + PolarValue::String(_) => PolarValueType::String, + PolarValue::Boolean(_) => PolarValueType::Boolean, + PolarValue::Map(_) => PolarValueType::Map, + PolarValue::List(_) => PolarValueType::List, + PolarValue::Variable(_) => PolarValueType::Variable, + PolarValue::Instance(i) => PolarValueType::Instance(i.debug_name()), + } + } +} + +#[derive(Clone, Debug)] +pub enum PolarValueType { + Integer, + Float, + String, + Boolean, + Map, + List, + Variable, + Instance(&'static str), +} + +impl std::fmt::Display for PolarValueType { + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + PolarValueType::Instance(name) => write!(fmt, "Instance<{}>", name), + _ => std::fmt::Debug::fmt(self, fmt), + } + } }