From afe817b987d221c1979c114e60e88ce7374c8ff9 Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Tue, 15 Oct 2024 08:35:12 +0200 Subject: [PATCH] Implement `Constraint` for `SingleValueSchema` --- .../src/schema/data_type/constraint/any_of.rs | 24 +++----------- .../src/schema/data_type/constraint/mod.rs | 31 +++++++++++++++++-- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/libs/@blockprotocol/type-system/rust/src/schema/data_type/constraint/any_of.rs b/libs/@blockprotocol/type-system/rust/src/schema/data_type/constraint/any_of.rs index f6c080c1a18..369a0aa6ff7 100644 --- a/libs/@blockprotocol/type-system/rust/src/schema/data_type/constraint/any_of.rs +++ b/libs/@blockprotocol/type-system/rust/src/schema/data_type/constraint/any_of.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use crate::schema::{ - ConstraintError, SingleValueSchema, ValueLabel, + ConstraintError, SingleValueSchema, data_type::{ closed::ResolveClosedDataTypeError, constraint::{Constraint, ConstraintValidator, ValueConstraints}, @@ -50,7 +50,7 @@ impl Constraint for AnyOfConstraints { .into_iter() .cartesian_product(other.any_of.clone()) { - let (constraints, remainder) = match lhs.constraints.combine(rhs.constraints) { + let (constraints, remainder) = match lhs.intersection(rhs) { Ok((constraints, remainder)) => (constraints, remainder), Err(error) => { errors.push(Err(error)); @@ -58,16 +58,7 @@ impl Constraint for AnyOfConstraints { } }; - let (description, label) = if lhs.description.is_none() && lhs.label.is_empty() { - (rhs.description, rhs.label) - } else { - (lhs.description, lhs.label) - }; - combined_constraints.push(SingleValueSchema { - description, - label, - constraints, - }); + combined_constraints.push(constraints); if let Some(remainder) = remainder { remainders.push(remainder); } @@ -75,7 +66,6 @@ impl Constraint for AnyOfConstraints { match combined_constraints.len() { 0 => { - // We now properly capture errors to return it to the caller. let _: Vec<()> = errors .into_iter() .try_collect_reports() @@ -86,12 +76,8 @@ impl Constraint for AnyOfConstraints { Self { any_of: combined_constraints, }, - remainders.pop().map(|constraints| Self { - any_of: vec![SingleValueSchema { - constraints, - description: None, - label: ValueLabel::default(), - }], + remainders.pop().map(|schema| Self { + any_of: vec![schema], }), )), _ => { diff --git a/libs/@blockprotocol/type-system/rust/src/schema/data_type/constraint/mod.rs b/libs/@blockprotocol/type-system/rust/src/schema/data_type/constraint/mod.rs index 0c5c838ec21..116102f2f80 100644 --- a/libs/@blockprotocol/type-system/rust/src/schema/data_type/constraint/mod.rs +++ b/libs/@blockprotocol/type-system/rust/src/schema/data_type/constraint/mod.rs @@ -139,7 +139,7 @@ impl Constraint for ValueConstraints { label: ValueLabel::default(), }], }; - lhs.combine(rhs) + lhs.intersection(rhs) .map(|(lhs, rhs)| (Self::from(lhs), rhs.map(Self::from))) } (Self::Typed(lhs), Self::AnyOf(rhs)) => { @@ -150,7 +150,7 @@ impl Constraint for ValueConstraints { label: ValueLabel::default(), }], }; - lhs.combine(rhs) + lhs.intersection(rhs) .map(|(lhs, rhs)| (Self::from(lhs), rhs.map(Self::from))) } (Self::AnyOf(lhs), Self::AnyOf(rhs)) => lhs @@ -256,6 +256,33 @@ pub struct SingleValueSchema { pub constraints: SingleValueConstraints, } +impl Constraint for SingleValueSchema { + fn intersection( + self, + other: Self, + ) -> Result<(Self, Option), Report> { + let (combined, remainder) = self.constraints.intersection(other.constraints)?; + let (description, label) = if self.description.is_none() && self.label.is_empty() { + (other.description, other.label) + } else { + (self.description, self.label) + }; + + Ok(( + Self { + description, + label, + constraints: combined, + }, + remainder.map(|remainder| Self { + constraints: remainder, + description: None, + label: ValueLabel::default(), + }), + )) + } +} + #[cfg(target_arch = "wasm32")] #[expect( dead_code,