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

@ -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()