Skip to content

Commit

Permalink
feat: add titles to enum types for better readability
Browse files Browse the repository at this point in the history
  • Loading branch information
willemneal committed Mar 20, 2024
1 parent b10e4be commit 0a686f1
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 9 deletions.
47 changes: 43 additions & 4 deletions src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,20 @@ pub enum Error {
GenerateJson(#[from] serde_json::Error),
}

use schemars::gen::SchemaSettings;
use schemars::{
gen::SchemaSettings,
schema::SchemaObject,
visit::{self, Visitor},
};
use std::str::FromStr;

pub struct Schema(pub schemars::schema::RootSchema);

impl TryFrom<crate::curr::TypeVariant> for Schema {
type Error = Error;
fn try_from(variant: crate::curr::TypeVariant) -> Result<Schema, Error> {
let settings = SchemaSettings::draft07();
println!("hhh");
let settings = SchemaSettings::draft07().with_visitor(ReplaceAdditionalProperties);
let generator = settings.into_generator();
Ok(Schema(variant.json_schema(generator)))
}
Expand All @@ -22,9 +29,41 @@ impl FromStr for Schema {
type Err = Error;
fn from_str(s: &str) -> Result<Schema, Error> {
s.parse::<crate::curr::TypeVariant>()
.map_err(|_| Error::UnknownType(s.to_string(), &crate::curr::TypeVariant::VARIANTS_STR))?
.map_err(|_| {
Error::UnknownType(s.to_string(), &crate::curr::TypeVariant::VARIANTS_STR)
})?
.try_into()
}
}

pub struct Schema(pub schemars::schema::RootSchema);
/// This visitor will remote "additionalProperties" from all objects in the schema.
#[derive(Debug, Clone)]
pub struct ReplaceAdditionalProperties;

impl Visitor for ReplaceAdditionalProperties {
fn visit_schema_object(&mut self, schema: &mut schemars::schema::SchemaObject) {
schema.object().additional_properties = None;
add_titles(schema.subschemas());
visit::visit_schema_object(self, schema);
}
}

/// This function will add titles to all one_of schemas in the schema. So that it is more readable.
/// E.g. it was `Option 1`, etc before
fn add_titles(sub_schema: &mut schemars::schema::SubschemaValidation) {
if let Some(ref mut one_of) = sub_schema.one_of {
one_of.iter_mut().for_each(|schema| {
if let schemars::schema::Schema::Object(ref mut obj) = schema {
if let Some(inner_obj) = &mut obj.object {
if let Some(title) = inner_obj.required.first() {
obj.metadata().title = Some(title.clone());
}
} else if let Some(enum_values) = &obj.enum_values {
if let Some(title) = enum_values.get(2) {
obj.metadata().title = Some(title.to_string());
}
}
}
});
}
}
9 changes: 4 additions & 5 deletions tests/serde_tx_schema.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
#![cfg(feature = "curr")]
#![cfg(all(feature = "schemars", feature = "serde", feature = "alloc"))]
#![cfg(feature = "wasm")]

use stellar_xdr::curr as stellar_xdr;
use stellar_xdr::{curr::TypeVariant, schema::Schema};

#[allow(clippy::too_many_lines)]
#[test]
fn test_serde_tx_schema() -> Result<(), Box<dyn std::error::Error>> {
let schema = schemars::schema_for!(stellar_xdr::ScVal);
let s = serde_json::to_string_pretty(&schema)?;
let schema: Schema = TypeVariant::ScVal.try_into()?;
let s = serde_json::to_string_pretty(&schema.0)?;
println!("{s}");
Ok(())
}

0 comments on commit 0a686f1

Please sign in to comment.