Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8aa15873b0 | |||
| 0d282cc930 | |||
| 581fc8e0c0 | |||
| 6f0bff8dc7 | |||
| 99c69e27ab |
@ -87,6 +87,34 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"schedule": {
|
||||||
|
"type": [
|
||||||
|
"opening_hours",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"season": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"label": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"opening_hours": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"open": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"seasons": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "season"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -262,6 +290,7 @@
|
|||||||
"uuid_field",
|
"uuid_field",
|
||||||
"tags",
|
"tags",
|
||||||
"ad_hoc",
|
"ad_hoc",
|
||||||
|
"schedule",
|
||||||
"$and",
|
"$and",
|
||||||
"$or"
|
"$or"
|
||||||
],
|
],
|
||||||
@ -277,6 +306,7 @@
|
|||||||
"uuid_field",
|
"uuid_field",
|
||||||
"tags",
|
"tags",
|
||||||
"ad_hoc",
|
"ad_hoc",
|
||||||
|
"schedule",
|
||||||
"$and",
|
"$and",
|
||||||
"$or"
|
"$or"
|
||||||
],
|
],
|
||||||
@ -298,6 +328,7 @@
|
|||||||
"uuid_field",
|
"uuid_field",
|
||||||
"tags",
|
"tags",
|
||||||
"ad_hoc",
|
"ad_hoc",
|
||||||
|
"schedule",
|
||||||
"$and",
|
"$and",
|
||||||
"$or"
|
"$or"
|
||||||
],
|
],
|
||||||
@ -366,6 +397,41 @@
|
|||||||
"string.condition",
|
"string.condition",
|
||||||
"null"
|
"null"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"schedule": {
|
||||||
|
"type": [
|
||||||
|
"filter",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"compiledPropertyNames": [
|
||||||
|
"open",
|
||||||
|
"seasons"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"open": {
|
||||||
|
"type": [
|
||||||
|
"string.condition",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"seasons": {
|
||||||
|
"type": [
|
||||||
|
"filter",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"compiledPropertyNames": [
|
||||||
|
"label"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"label": {
|
||||||
|
"type": [
|
||||||
|
"string.condition",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"type": "filter"
|
"type": "filter"
|
||||||
@ -483,7 +549,9 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"opening_hours": {},
|
||||||
|
"season": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,10 +26,14 @@ impl Schema {
|
|||||||
if let Some(items) = &child.obj.items {
|
if let Some(items) = &child.obj.items {
|
||||||
if !items.is_proxy() {
|
if !items.is_proxy() {
|
||||||
structural_filter = items.compile_filter(_db, "", _errors);
|
structural_filter = items.compile_filter(_db, "", _errors);
|
||||||
|
} else if let Some(target) = Self::value_type_target(items, _db) {
|
||||||
|
structural_filter = target.compile_filter(_db, "", _errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if !child.is_proxy() {
|
} else if !child.is_proxy() {
|
||||||
structural_filter = child.compile_filter(_db, "", _errors);
|
structural_filter = child.compile_filter(_db, "", _errors);
|
||||||
|
} else if let Some(target) = Self::value_type_target(child, _db) {
|
||||||
|
structural_filter = target.compile_filter(_db, "", _errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(mut inline_schema) = structural_filter {
|
if let Some(mut inline_schema) = structural_filter {
|
||||||
@ -117,6 +121,37 @@ impl Schema {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resolves a pure type-pointer schema to a named non-table value type's own schema —
|
||||||
|
/// a reusable, schema-only object (e.g. an operating-hours config). Naming a value type
|
||||||
|
/// is a reuse choice, not a semantics choice: it filters structurally, exactly like an
|
||||||
|
/// inline object. Table-backed boundaries keep the lazy {type}.filter reference instead.
|
||||||
|
fn value_type_target<'a>(schema: &Arc<Schema>, db: &'a Database) -> Option<&'a Arc<Schema>> {
|
||||||
|
let t = match &schema.obj.type_ {
|
||||||
|
Some(SchemaTypeOrArray::Single(t)) => Some(t.as_str()),
|
||||||
|
Some(SchemaTypeOrArray::Multiple(types)) => {
|
||||||
|
types.iter().find(|t| *t != "null").map(|s| s.as_str())
|
||||||
|
}
|
||||||
|
None => None,
|
||||||
|
}?;
|
||||||
|
if matches!(
|
||||||
|
t,
|
||||||
|
"string" | "integer" | "number" | "boolean" | "object" | "array" | "null"
|
||||||
|
) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if t.ends_with(".condition") || t.ends_with(".filter") {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if db.enums.contains_key(t) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let base = t.split('.').next_back().unwrap_or(t);
|
||||||
|
if db.types.contains_key(base) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
db.schemas.get(t)
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_filter_type(schema: &Arc<Schema>, db: &Database) -> Option<Vec<String>> {
|
fn resolve_filter_type(schema: &Arc<Schema>, db: &Database) -> Option<Vec<String>> {
|
||||||
if let Some(type_) = &schema.obj.type_ {
|
if let Some(type_) = &schema.obj.type_ {
|
||||||
match type_ {
|
match type_ {
|
||||||
@ -151,6 +186,7 @@ impl Schema {
|
|||||||
"number" => Some(vec!["number.condition".to_string()]),
|
"number" => Some(vec!["number.condition".to_string()]),
|
||||||
"boolean" => Some(vec!["boolean.condition".to_string()]),
|
"boolean" => Some(vec!["boolean.condition".to_string()]),
|
||||||
"object" => None, // Inline structures are ignored in Composed References
|
"object" => None, // Inline structures are ignored in Composed References
|
||||||
|
"dict" => None, // Dynamic dictionary maps are ignored in Composed References
|
||||||
"array" => {
|
"array" => {
|
||||||
if let Some(items) = &schema.obj.items {
|
if let Some(items) = &schema.obj.items {
|
||||||
return Self::resolve_filter_type(items, db);
|
return Self::resolve_filter_type(items, db);
|
||||||
@ -164,8 +200,16 @@ impl Schema {
|
|||||||
} else if db.enums.contains_key(custom) {
|
} else if db.enums.contains_key(custom) {
|
||||||
Some(vec![format!("{}.condition", custom)])
|
Some(vec![format!("{}.condition", custom)])
|
||||||
} else {
|
} else {
|
||||||
// Assume anything else is a Relational cross-boundary that already has its own .filter dynamically built
|
// A Relational cross-boundary gets a reference to the target's dynamically built
|
||||||
Some(vec![format!("{}.filter", custom)])
|
// .filter — but only a table-backed boundary has one. A named non-table value type
|
||||||
|
// compiles structurally upstream (value_type_target); reaching here means it had
|
||||||
|
// no compilable structure — omit it rather than emit a dangling .filter reference.
|
||||||
|
let base = custom.split('.').next_back().unwrap_or(custom);
|
||||||
|
if db.types.contains_key(base) {
|
||||||
|
Some(vec![format!("{}.filter", custom)])
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -125,6 +125,7 @@ impl Schema {
|
|||||||
child.compile(db, root_id, format!("{}/{}", path, k), errors);
|
child.compile(db, root_id, format!("{}/{}", path, k), errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(items) = &self.obj.items {
|
if let Some(items) = &self.obj.items {
|
||||||
items.compile(db, root_id, format!("{}/items", path), errors);
|
items.compile(db, root_id, format!("{}/items", path), errors);
|
||||||
}
|
}
|
||||||
@ -138,6 +139,7 @@ impl Schema {
|
|||||||
if let Some(child) = &self.obj.not {
|
if let Some(child) = &self.obj.not {
|
||||||
child.compile(db, root_id, format!("{}/not", path), errors);
|
child.compile(db, root_id, format!("{}/not", path), errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(child) = &self.obj.contains {
|
if let Some(child) = &self.obj.contains {
|
||||||
child.compile(db, root_id, format!("{}/contains", path), errors);
|
child.compile(db, root_id, format!("{}/contains", path), errors);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user