Open jrcarl624 opened 1 year ago
Also wouldn't it be a better approach to use an enum for anyOf
The "Transitions" schema seems to contain an error:
"transitions": {
"title": "Transition",
"description": "The transition definition for.",
"minProperties": 1,
"type": "array",
...
This is an array
with minProperties
which is only valid for object
types. I think it should be minItems
: https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-validation-02#section-6.4.2
As it stands I believe that this schema is unsatisfiable in the most pedantic sense. That is to say, a type can't both be an array and have at least one object property.
It's hard to know what to do with these kinds of mis-formed schemas. We could try to infer what the intent was, but that's a slippery slope that can lead to bad assumptions. I recognize that this is a JSON schema whose content you don't control. Typify could do more to explain the problem (e.g. "object validation on array
type"); then I'd suggest you could use something like JSON patch to clean it up, or a more general "JSON schema cleaner" to look for mistakes such as this.
The only path forward I can see here that we could handle is to ignore fields that are inconsistent with the type
field.
While looking into #230 it does look like it's reasonable--maybe even correct--to ignore constraints unrelated to the type
. I'll implement that when I have the chance.
While looking into #230 it does look like it's reasonable--maybe even correct--to ignore constraints unrelated to the
type
. I'll implement that when I have the chance.
Looking into this later I have validated the schema and it did not error out so the schema is correct according to draft 7
{
"$id": "blockception.minecraft.language_names",
"$schema": "http://json-schema.org/draft-07/schema",
"additionalProperties": false,
"definitions": {},
"description": "A language names definitions file.",
"examples": [
[
[
"en_US",
"English (US)"
],
[
"en_GB",
"English (UK)"
],
[
"de_DE",
"Deutsch (Deutschland)"
],
[
"es_ES",
"Español (España)"
],
[
"es_MX",
"Español (México)"
],
[
"fr_FR",
"Français (France)"
],
[
"fr_CA",
"Français (Canada)"
],
[
"it_IT",
"Italiano (Italia)"
],
[
"ja_JP",
"日本語 (日本)"
],
[
"ko_KR",
"한국어 (대한민국)"
],
[
"pt_BR",
"Português (Brasil)"
],
[
"pt_PT",
"Português (Portugal)"
],
[
"ru_RU",
"Русский (Россия)"
],
[
"zh_CN",
"简体中文"
],
[
"zh_TW",
"繁體中文"
],
[
"nl_NL",
"Nederlands (Nederland)"
],
[
"bg_BG",
"Български (BG)"
],
[
"cs_CZ",
"Čeština (Česká republika)"
],
[
"da_DK",
"Dansk (DA)"
],
[
"el_GR",
"Ελληνικά (Ελλάδα)"
],
[
"fi_FI",
"Suomi (Suomi)"
],
[
"hu_HU",
"Magyar (HU)"
],
[
"id_ID",
"Bahasa Indonesia (Indonesia)"
],
[
"nb_NO",
"Norsk bokmål (Norge)"
],
[
"pl_PL",
"Polski (PL)"
],
[
"sk_SK",
"Slovensky (SK)"
],
[
"sv_SE",
"Svenska (Sverige)"
],
[
"tr_TR",
"Türkçe (Türkiye)"
],
[
"uk_UA",
"Українська (Україна)"
]
]
],
"items": {
"description": "A language name identifier.",
"items": [
{
"description": "A language identifier.",
"pattern": "^[a-z]{2}_[A-Z]{2}$",
"type": "string"
},
{
"description": "The name of the language.",
"type": "string"
}
],
"type": "array"
},
"title": "Language Names",
"type": "array"
}
I dont seem to understand why this errors out, this is something when I have run into.
The first schema you mentioned should be addressed by #255 which fixes #253. The second schema you mentioned is more complex. If it had
"minItems": 2,
"maxItems": 2,
... it would be pretty simple to model as Vec<(StringWithRegex, String)>
but because it doesn't, we need a type more like this:
struct ArrayItem(Option<StringWithRegex>, Option<String>, Vec<serde_json::Value>);
The inner array schema validates with an array of any number of items as long as the first two (if present) conform the string-with-regex, and string respectively. I've opened #254 to track that work more specifically.
Or maybe something like this--assuming we would prefer that only valid states are representable in Rust:
enum ArrayItem {
pub Items0,
pub Items1(StringWithRegex),
pub Items2(StringWithRegex, String),
pub ItemsN(StringWithRegex, String, Vec<serde_json::Value>),
}
impl ArrayItem {
pub fn get0(&self) -> Option<&StringWithRegex> {
match self {
Self::Items1(zero) | Self::Items2(zero, ..) | Self::ItemsN(zero, ..) => Some(zero),
_ => None,
}
}
pub fn get1(&self) -> Option<&StringWithRegex> {
match self {
Self::Items2(_, one) | Self::ItemsN(_, one, ..) => Some(one),
_ => None,
}
}
// ...
}
We could generate something to make it easier to construct:
mod builder {
struct ArrayItem(Option<StringWithRegex>, Option<String>, Vec<serde_json::Value>);
pub fn with_0(self, item_0: StringWithRegex) -> Self {
let (_, item_1, rest) = self;
Self(Some(item_0), item_1, rest)
}
// ...
impl std::convert::TryFrom<ArrayItem> for super::ArrayItem {
fn try_from(value: ArrayItem) -> Result<super::ArrayItem, String> {
match self {
(None, None, rest) if rest.is_empty() => Ok(Self::Items0),
(Some(zero), None, rest) if rest.is_empty() => Ok(Self::Items1(zero)),
(Some(zero), Some(one), rest) if rest.is_empty() => Ok(Self::Items2(zero, one)),
(Some(zero), Some(one), rest) => Ok(Self::ItemsN(zero, one, rest)),
_ => Err("nope".to_string()),
}
}
}
}
.1.0 (C:\Users\miner\OneDrive\Documents\GitHub\Androecia\FriendConnect-rs\minecraft-bedrock-schemas-rs)`
Caused by: process didn't exit successfully: C:\Users\miner\OneDrive\Documents\GitHub\Androecia\FriendConnect-rs\minecraft-bedrock-schemas-rs\target\debug\build\minecraft-bedrock-schemas-89cec1978fa2cbc3\build-script-build (exit code: 101) --- stdout Writing to: .\src\behavior\animations\animations.rs Writing to: .\src\behavior\animation_controllers\animation_controller.rs
--- stderr thread 'main' panicked at 'not yet implemented: invalid (or unexpected) schema: SchemaObject { metadata: Some( Metadata { id: None, title: Some( "Transition", ), description: Some( "The transition definition for.", ), default: None, deprecated: false, read_only: false, write_only: false, examples: [], }, ), instance_type: Some( Single( Array, ), ), format: None, enum_values: None, const_value: None, subschemas: None, number: None, string: None, array: Some( ArrayValidation { items: Some( Single( Object( SchemaObject { metadata: Some( Metadata { id: None, title: Some( "Transition", ), description: Some( "A transition to another state.", ), default: None, deprecated: false, read_only: false, write_only: false, examples: [ Object { "default": String("query.is_chested"), }, ], }, ), instance_type: Some( Single( Object, ), ), format: None, enum_values: None, const_value: None, subschemas: None, number: None, string: None, array: None, object: Some( ObjectValidation { max_properties: Some( 1, ), min_properties: Some( 1, ), required: {}, properties: {}, pattern_properties: {}, additional_properties: Some( Object( SchemaObject { metadata: None, instance_type: None, format: None, enum_values: None, const_value: None, subschemas: None, number: None, string: None, array: None, object: None, reference: Some( "#/definitions/A", ), extensions: {}, }, ), ), property_names: None, }, ), reference: None, extensions: {}, }, ), ), ), additional_items: None, max_items: None, min_items: None, unique_items: None, contains: None, }, ), object: Some( ObjectValidation { max_properties: None, min_properties: Some( 1, ), required: {}, properties: {}, pattern_properties: {}, additional_properties: None, property_names: None, }, ), reference: None, extensions: {}, }', typify\typify-impl\src\convert.rs:551:36