use schemars::{
schema::{InstanceType, Schema, SchemaObject, SingleOrVec, StringValidation},
JsonSchema,
};
impl JsonSchema for crate::ISIN {
fn schema_name() -> String {
"ISIN".to_string()
}
fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> Schema {
let schema = SchemaObject {
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::String))),
string: Some(Box::new(StringValidation {
pattern: Some("^[A-Z]{2}[0-9A-Z]{9}[0-9]$".to_string()),
..Default::default()
})),
..Default::default()
};
schema.into()
}
}
#[cfg(test)]
mod tests {
use schemars::schema_for;
#[test]
fn schema_generation() {
let schema = schema_for!(crate::ISIN);
assert_eq!(
schema
.schema
.metadata
.as_ref()
.unwrap()
.title
.as_ref()
.unwrap(),
"ISIN"
);
}
#[test]
fn schema_validation() {
use jsonschema::Validator;
use serde_json::json;
let schema = schema_for!(crate::ISIN);
let compiled_schema = Validator::new(&serde_json::to_value(schema).unwrap())
.expect("Schema compilation failed");
assert!(compiled_schema.is_valid(&json!("US0378331005"))); assert!(compiled_schema.is_valid(&json!("JP3788600009"))); assert!(compiled_schema.is_valid(&json!("IE00BFXC1P95")));
assert!(!compiled_schema.is_valid(&json!("US037833100"))); assert!(!compiled_schema.is_valid(&json!("US0378331005X"))); assert!(!compiled_schema.is_valid(&json!("us0378331005"))); assert!(!compiled_schema.is_valid(&json!("US037833100A"))); assert!(!compiled_schema.is_valid(&json!(123456789012i64))); assert!(!compiled_schema.is_valid(&json!(""))); }
#[cfg(all(feature = "serde", feature = "schemars"))]
#[test]
fn schema_matches_serde() {
use jsonschema::Validator;
use serde_json::json;
let schema = schema_for!(crate::ISIN);
let compiled_schema = Validator::new(&serde_json::to_value(schema).unwrap())
.expect("Schema compilation failed");
let valid_isin = "US0378331005";
let parsed_isin = crate::parse(valid_isin).unwrap();
let serialized = serde_json::to_value(parsed_isin).unwrap();
assert!(compiled_schema.is_valid(&serialized));
assert!(compiled_schema.is_valid(&json!(valid_isin)));
}
#[cfg(all(feature = "serde", feature = "schemars"))]
#[test]
fn struct_with_isin_roundtrip() {
use jsonschema::Validator;
use serde::{Deserialize, Serialize};
use serde_json::json;
#[derive(Serialize, Deserialize, schemars::JsonSchema)]
struct SecurityInfo {
isin: crate::ISIN,
name: String,
}
let schema = schema_for!(SecurityInfo);
let compiled_schema = Validator::new(&serde_json::to_value(schema).unwrap())
.expect("Schema compilation failed");
let test_data = json!({
"isin": "US0378331005",
"name": "Apple Inc."
});
assert!(compiled_schema.is_valid(&test_data));
let security: SecurityInfo = serde_json::from_value(test_data).unwrap();
assert_eq!(security.isin.to_string(), "US0378331005");
assert_eq!(security.name, "Apple Inc.");
}
#[test]
fn edge_case_patterns() {
use jsonschema::Validator;
use serde_json::json;
let schema = schema_for!(crate::ISIN);
let compiled_schema = Validator::new(&serde_json::to_value(schema).unwrap())
.expect("Schema compilation failed");
assert!(compiled_schema.is_valid(&json!("XS2021448886"))); assert!(compiled_schema.is_valid(&json!("EZR9HY1361L7"))); assert!(compiled_schema.is_valid(&json!("DE000A0GNPZ3"))); assert!(compiled_schema.is_valid(&json!("GB00BF0FCW58")));
assert!(!compiled_schema.is_valid(&json!("A20378331005"))); assert!(!compiled_schema.is_valid(&json!("US037833100A"))); assert!(!compiled_schema.is_valid(&json!("US037833-005"))); }
}