Assorted tweaks to support external playground crate (#322)

* Assorted tweaks to support external playground crate

* Fix schemas

* Fixed schema again

* Add ToHex for RawValue

* Add FromHex to RawValue
This commit is contained in:
Rob Knight 2025-07-02 18:27:54 +02:00 committed by GitHub
parent 335100d1d7
commit 24cafde231
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 111 additions and 46 deletions

View file

@ -125,6 +125,40 @@ impl fmt::Display for RawValue {
}
}
impl ToHex for RawValue {
fn encode_hex<T: std::iter::FromIterator<char>>(&self) -> T {
self.0
.iter()
.rev()
.fold(String::with_capacity(64), |mut s, limb| {
write!(s, "{:016x}", limb.0).unwrap();
s
})
.chars()
.collect()
}
fn encode_hex_upper<T: std::iter::FromIterator<char>>(&self) -> T {
self.0
.iter()
.rev()
.fold(String::with_capacity(64), |mut s, limb| {
write!(s, "{:016X}", limb.0).unwrap();
s
})
.chars()
.collect()
}
}
impl FromHex for RawValue {
type Error = FromHexError;
fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
Hash::from_hex(hex).map(|h| RawValue(h.0))
}
}
#[derive(Clone, Copy, Debug, Default, Hash, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct Hash(
#[serde(

View file

@ -9,7 +9,7 @@ use crate::middleware::{
EMPTY_HASH, F, VALUE_SIZE,
};
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
pub struct Wildcard {
pub name: String,
pub index: usize,
@ -37,7 +37,7 @@ impl ToFields for Wildcard {
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "type", content = "value")]
pub enum StatementTmplArg {
None,
@ -122,7 +122,7 @@ impl fmt::Display for StatementTmplArg {
}
/// Statement Template for a Custom Predicate
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
pub struct StatementTmpl {
pub pred: Predicate,
pub args: Vec<StatementTmplArg>,
@ -179,7 +179,7 @@ impl ToFields for StatementTmpl {
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
/// NOTE: fields are not public (outside of crate) to enforce the struct instantiation through
/// the `::and/or` methods, which performs checks on the values.
@ -275,6 +275,21 @@ impl CustomPredicate {
args: vec![],
}
}
pub fn is_conjunction(&self) -> bool {
self.conjunction
}
pub fn is_disjunction(&self) -> bool {
!self.conjunction
}
pub fn statements(&self) -> &[StatementTmpl] {
&self.statements
}
pub fn args_len(&self) -> usize {
self.args_len
}
pub fn wildcard_names(&self) -> &[String] {
&self.wildcard_names
}
}
impl ToFields for CustomPredicate {
@ -341,13 +356,19 @@ impl fmt::Display for CustomPredicate {
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct CustomPredicateBatch {
id: Hash,
pub name: String,
pub(crate) predicates: Vec<CustomPredicate>,
}
impl std::hash::Hash for CustomPredicateBatch {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.id.hash(state);
}
}
impl ToFields for CustomPredicateBatch {
fn to_fields(&self, params: &Params) -> Vec<F> {
// all the custom predicates in order
@ -401,7 +422,7 @@ impl CustomPredicateBatch {
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
pub struct CustomPredicateRef {
pub batch: Arc<CustomPredicateBatch>,
pub index: usize,

View file

@ -53,8 +53,6 @@ pub enum TypedValue {
// 53-bit precision for integers, integers are represented as tagged
// strings, with a custom serializer and deserializer.
// TAGGED TYPES:
Set(Set),
Dictionary(Dictionary),
Int(
#[serde(serialize_with = "serialize_i64", deserialize_with = "deserialize_i64")]
// #[schemars(with = "String", regex(pattern = r"^\d+$"))]
@ -67,6 +65,10 @@ pub enum TypedValue {
PodId(PodId),
// UNTAGGED TYPES:
#[serde(untagged)]
Set(Set),
#[serde(untagged)]
Dictionary(Dictionary),
#[serde(untagged)]
Array(Array),
#[serde(untagged)]
String(String),
@ -170,6 +172,20 @@ impl TryFrom<TypedValue> for Key {
}
}
impl TryFrom<&TypedValue> for PodId {
type Error = Error;
fn try_from(v: &TypedValue) -> Result<Self> {
match v {
TypedValue::PodId(id) => Ok(*id),
TypedValue::Raw(v) => Ok(PodId(Hash(v.0))),
_ => Err(Error::custom(format!(
"Value {} cannot be converted to a PodId.",
v
))),
}
}
}
impl fmt::Display for TypedValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
@ -216,30 +232,6 @@ impl JsonSchema for TypedValue {
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
use schemars::schema::{InstanceType, Schema, SchemaObject, SingleOrVec};
let set_schema = schemars::schema::SchemaObject {
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Object))),
object: Some(Box::new(schemars::schema::ObjectValidation {
properties: [("Set".to_string(), gen.subschema_for::<Set>())]
.into_iter()
.collect(),
required: ["Set".to_string()].into_iter().collect(),
..Default::default()
})),
..Default::default()
};
let dictionary_schema = schemars::schema::SchemaObject {
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Object))),
object: Some(Box::new(schemars::schema::ObjectValidation {
properties: [("Dictionary".to_string(), gen.subschema_for::<Dictionary>())]
.into_iter()
.collect(),
required: ["Dictionary".to_string()].into_iter().collect(),
..Default::default()
})),
..Default::default()
};
// Int is serialized/deserialized as a tagged string
let int_schema = schemars::schema::SchemaObject {
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Object))),
@ -275,20 +267,36 @@ impl JsonSchema for TypedValue {
..Default::default()
};
let public_key_schema = schemars::schema::SchemaObject {
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Object))),
object: Some(Box::new(schemars::schema::ObjectValidation {
// PublicKey is serialized as a string
properties: [("PublicKey".to_string(), gen.subschema_for::<String>())]
.into_iter()
.collect(),
required: ["PublicKey".to_string()].into_iter().collect(),
..Default::default()
})),
..Default::default()
};
// This is the part that Schemars can't generate automatically:
let untagged_array_schema = gen.subschema_for::<Array>();
let untagged_set_schema = gen.subschema_for::<Set>();
let untagged_dictionary_schema = gen.subschema_for::<Dictionary>();
let untagged_string_schema = gen.subschema_for::<String>();
let untagged_bool_schema = gen.subschema_for::<bool>();
Schema::Object(SchemaObject {
subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
any_of: Some(vec![
Schema::Object(set_schema),
Schema::Object(dictionary_schema),
Schema::Object(int_schema),
Schema::Object(raw_schema),
Schema::Object(public_key_schema),
untagged_array_schema,
untagged_dictionary_schema,
untagged_string_schema,
untagged_set_schema,
untagged_bool_schema,
]),
..Default::default()

View file

@ -56,7 +56,7 @@ impl ToFields for OperationType {
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum NativeOperation {
None = 0,
NewEntry = 1,

View file

@ -50,7 +50,7 @@ impl ToFields for NativePredicate {
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "type", content = "value")]
pub enum Predicate {
Native(NativePredicate),
@ -129,7 +129,7 @@ impl fmt::Display for Predicate {
}
/// Type encapsulating statements with their associated arguments.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "predicate", content = "args")]
pub enum Statement {
None,
@ -368,7 +368,8 @@ impl ToFields for StatementArg {
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "type", content = "value")]
pub enum ValueRef {
Literal(Value),
Key(AnchoredKey),