Skip to main content
Glama
cas.rs4.26 kB
use std::collections::BTreeMap; #[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize, Clone)] pub enum CasValueNumber { U64(u64), I64(i64), F64(f64), } // (Comment copied from serde_json::Number's equivalent "N" type) // Implementing Eq is fine since any float values are always finite. impl Eq for CasValueNumber {} /// A type that can be converted to and from serde_json::Value types infallibly, /// *so long as* arbitrary precision arithmetic is not enabled for serde_json. /// This is necessary because postcard will *not* deserialize serde_json's `Number` /// type, but we still want to store arbitrary payloads in our content store. /// The alternative is to serialize the value to a string and then serialize /// that string with postcard. #[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize, Clone)] #[remain::sorted] pub enum CasValue { /// An array of values Array(Vec<CasValue>), /// A boolean scalar Bool(bool), /// A null value Null, /// A Number value. JSON numbers are either double precision IEEE floating point values, or /// they in some implementations can be BigInt values. However, we're currently only going to /// support double precision floats and 64 bit integers. If arbitrary precision integers are /// enabled for serde_json, this *will* cause a panic. Number(CasValueNumber), /// An object. BTreeMap is the internal representation used by serde_json for objects, /// *unless* order preservation is enabled. If order preservation is enabled, we will /// lose that ordering information in the conversion to/from `serde_json::Value``. Object(BTreeMap<String, CasValue>), /// A string scalar value String(String), } // todo: make this non-recursive for maps and arrays impl From<serde_json::Value> for CasValue { fn from(value: serde_json::Value) -> Self { match value { serde_json::Value::Null => Self::Null, serde_json::Value::Bool(b) => Self::Bool(b), serde_json::Value::Number(n) => CasValue::Number(if n.is_u64() { CasValueNumber::U64( n.as_u64() .expect("serde_json said it was a u64 but refused to give me one"), ) } else if n.is_i64() { CasValueNumber::I64( n.as_i64() .expect("serde_json said it was an i64 but refused to give me one"), ) } else if n.is_f64() { CasValueNumber::F64( n.as_f64() .expect("serde_json said it was an f64 but refused to give me one"), ) } else { panic!("the arbitrary_precision feature of serde_json is not supported"); }), serde_json::Value::Array(mut a) => Self::Array(a.drain(..).map(|e| e.into()).collect()), serde_json::Value::String(s) => Self::String(s), // Can we avoid these clones? serde_json::Value::Object(map) => Self::Object( map.iter() .map(|(k, v)| (k.to_owned(), v.to_owned().into())) .collect(), ), } } } impl From<CasValue> for serde_json::Value { fn from(value: CasValue) -> Self { match value { CasValue::Null => serde_json::Value::Null, CasValue::Bool(b) => serde_json::Value::Bool(b), CasValue::Array(mut a) => { serde_json::Value::Array(a.drain(..).map(Into::into).collect()) } CasValue::Number(n) => serde_json::Value::Number(match n { CasValueNumber::U64(n) => n.into(), CasValueNumber::I64(n) => n.into(), CasValueNumber::F64(n) => serde_json::value::Number::from_f64(n) .expect("cannot deserialize an infinite or NAN f64 value"), }), CasValue::String(s) => serde_json::Value::String(s), CasValue::Object(map) => serde_json::Value::Object( map.iter() .map(|(k, v)| (k.to_owned(), v.to_owned().into())) .collect(), ), } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server