Skip to main content

icydb_core/value/
semantics.rs

1//! Module: value::semantics
2//!
3//! Responsibility: semantic classification for dynamic `Value` variants.
4//! Does not own: operator execution, map normalization, or numeric conversion.
5//! Boundary: lightweight capability and coercion-family classification.
6
7use crate::value::{CoercionFamily, Value};
8
9// Preserve independent capability flags through const matches generated from
10// the canonical registry. Collections and null have no scalar capability.
11macro_rules! numeric_capabilities_from_registry {
12    ( @args $value:expr; @entries $( ($scalar:ident, $coercion_family:expr, $value_pat:pat, is_numeric_value = $is_numeric:expr, supports_numeric_coercion = $supports_numeric_coercion:expr, supports_arithmetic = $supports_arithmetic:expr, supports_equality = $supports_equality:expr, supports_ordering = $supports_ordering:expr, is_keyable = $is_keyable:expr, is_primary_key_component_encodable = $is_primary_key_component_encodable:expr) ),* $(,)? ) => {
13        match $value {
14            $( $value_pat => ($is_numeric, $supports_numeric_coercion), )*
15            Value::List(_) | Value::Map(_) | Value::Null => (false, false),
16        }
17    };
18}
19
20#[must_use]
21const fn is_numeric(value: &Value) -> bool {
22    scalar_registry!(numeric_capabilities_from_registry, value).0
23}
24
25#[must_use]
26pub(crate) const fn supports_numeric_coercion(value: &Value) -> bool {
27    scalar_registry!(numeric_capabilities_from_registry, value).1
28}
29
30/// Returns the coercion-routing family for this value.
31#[must_use]
32const fn coercion_family(value: &Value) -> CoercionFamily {
33    match value {
34        Value::Account(_) | Value::Principal(_) | Value::Ulid(_) => CoercionFamily::Identifier,
35        Value::Blob(_) | Value::Subaccount(_) => CoercionFamily::Blob,
36        Value::Bool(_) => CoercionFamily::Bool,
37        Value::Date(_)
38        | Value::Decimal(_)
39        | Value::Duration(_)
40        | Value::Float32(_)
41        | Value::Float64(_)
42        | Value::Int64(_)
43        | Value::Int128(_)
44        | Value::Timestamp(_)
45        | Value::Nat64(_)
46        | Value::Nat128(_)
47        | Value::U256(_) => CoercionFamily::Numeric,
48        Value::Enum(_) => CoercionFamily::Enum,
49        Value::List(_) | Value::Map(_) => CoercionFamily::Collection,
50        Value::Null => CoercionFamily::Null,
51        Value::Text(_) => CoercionFamily::Textual,
52        Value::Unit => CoercionFamily::Unit,
53    }
54}
55
56impl Value {
57    /// Returns true if the value is one of the numeric-like variants
58    /// supported by numeric comparison/ordering.
59    #[must_use]
60    pub const fn is_numeric(&self) -> bool {
61        is_numeric(self)
62    }
63
64    /// Returns true when numeric coercion/comparison is explicitly allowed.
65    #[must_use]
66    pub const fn supports_numeric_coercion(&self) -> bool {
67        supports_numeric_coercion(self)
68    }
69
70    /// Returns the coercion-routing family for this value.
71    ///
72    /// NOTE:
73    /// This does NOT imply numeric, arithmetic, ordering, or keyability support.
74    /// All scalar capabilities are registry-driven.
75    #[must_use]
76    pub const fn coercion_family(&self) -> CoercionFamily {
77        coercion_family(self)
78    }
79}