///|
pub(all) enum Value {
Text(String)
Integer(Int64)
Decimal(Double)
Boolean(Bool)
NullValue
} derive(Eq, @debug.Debug)
///|
pub extend Value with Eq::{equal, not_equal}
///|
pub extend Value with @debug.Debug::{to_repr}
///|
pub(all) struct Field {
name : String
value : Value
} derive(Eq, @debug.Debug)
///|
pub extend Field with Eq::{equal, not_equal}
///|
pub extend Field with @debug.Debug::{to_repr}
///|
pub fn Value::validate(self : Value) -> Unit raise CepError {
match self {
Decimal(value) =>
if !finite(value) {
raise Invalid(path="value", reason="decimal must be finite")
}
Text(value) =>
if value.length() > 4096 {
raise Resource(resource="text code units", limit=4096)
}
_ => ()
}
}
///|
pub fn Value::type_name(self : Value) -> String {
match self {
Text(_) => "text"
Integer(_) => "integer"
Decimal(_) => "decimal"
Boolean(_) => "boolean"
NullValue => "null"
}
}
///|
pub(all) enum Comparison {
Equal
NotEqual
Less
LessEqual
Greater
GreaterEqual
} derive(Eq, @debug.Debug)
///|
pub extend Comparison with Eq::{equal, not_equal}
///|
pub extend Comparison with @debug.Debug::{to_repr}
///|
fn compare_order(order : Int32, comparison : Comparison) -> Bool {
match comparison {
Equal => order == 0
NotEqual => order != 0
Less => order < 0
LessEqual => order <= 0
Greater => order > 0
GreaterEqual => order >= 0
}
}
///|
/// Comparisons never coerce integer values to floating point.
pub fn Value::compare(
self : Value,
comparison : Comparison,
other : Value,
) -> Bool {
match (self, other) {
(Integer(a), Integer(b)) => compare_order(a.compare(b), comparison)
(Decimal(a), Decimal(b)) =>
finite(a) && finite(b) && compare_order(a.compare(b), comparison)
(Text(a), Text(b)) => compare_order(a.compare(b), comparison)
(Boolean(a), Boolean(b)) =>
match comparison {
Equal => a == b
NotEqual => a != b
_ => false
}
(NullValue, NullValue) => comparison == Equal
_ => false
}
}