diff --git a/db/src/schema.rs b/db/src/schema.rs index ccd79093..bf1d22a5 100644 --- a/db/src/schema.rs +++ b/db/src/schema.rs @@ -223,30 +223,32 @@ impl SchemaBuilding for Schema { pub trait SchemaTypeChecking { /// Do schema-aware typechecking and coercion. /// - /// Either assert that the given value is in the attribute's value set, or (in limited cases) - /// coerce the given value into the attribute's value set. - fn to_typed_value(&self, value: &edn::Value, attribute: &Attribute) -> Result; + /// Either assert that the given value is in the value type's value set, or (in limited cases) + /// coerce the given value into the value type's value set. + fn to_typed_value(&self, value: &edn::Value, value_type: ValueType) -> Result; } impl SchemaTypeChecking for Schema { - fn to_typed_value(&self, value: &edn::Value, attribute: &Attribute) -> Result { - // TODO: encapsulate entid-ident-attribute for better error messages. + fn to_typed_value(&self, value: &edn::Value, value_type: ValueType) -> Result { + // TODO: encapsulate entid-ident-attribute for better error messages, perhaps by including + // the attribute (rather than just the attribute's value type) into this function or a + // wrapper function. match TypedValue::from_edn_value(value) { // We don't recognize this EDN at all. Get out! - None => bail!(ErrorKind::BadEDNValuePair(value.clone(), attribute.value_type.clone())), - Some(typed_value) => match (&attribute.value_type, typed_value) { + None => bail!(ErrorKind::BadEDNValuePair(value.clone(), value_type)), + Some(typed_value) => match (value_type, typed_value) { // Most types don't coerce at all. - (&ValueType::Boolean, tv @ TypedValue::Boolean(_)) => Ok(tv), - (&ValueType::Long, tv @ TypedValue::Long(_)) => Ok(tv), - (&ValueType::Double, tv @ TypedValue::Double(_)) => Ok(tv), - (&ValueType::String, tv @ TypedValue::String(_)) => Ok(tv), - (&ValueType::Uuid, tv @ TypedValue::Uuid(_)) => Ok(tv), - (&ValueType::Keyword, tv @ TypedValue::Keyword(_)) => Ok(tv), + (ValueType::Boolean, tv @ TypedValue::Boolean(_)) => Ok(tv), + (ValueType::Long, tv @ TypedValue::Long(_)) => Ok(tv), + (ValueType::Double, tv @ TypedValue::Double(_)) => Ok(tv), + (ValueType::String, tv @ TypedValue::String(_)) => Ok(tv), + (ValueType::Uuid, tv @ TypedValue::Uuid(_)) => Ok(tv), + (ValueType::Keyword, tv @ TypedValue::Keyword(_)) => Ok(tv), // Ref coerces a little: we interpret some things depending on the schema as a Ref. - (&ValueType::Ref, TypedValue::Long(x)) => Ok(TypedValue::Ref(x)), - (&ValueType::Ref, TypedValue::Keyword(ref x)) => self.require_entid(&x).map(|entid| TypedValue::Ref(entid)), + (ValueType::Ref, TypedValue::Long(x)) => Ok(TypedValue::Ref(x)), + (ValueType::Ref, TypedValue::Keyword(ref x)) => self.require_entid(&x).map(|entid| TypedValue::Ref(entid)), // Otherwise, we have a type mismatch. - (value_type, _) => bail!(ErrorKind::BadEDNValuePair(value.clone(), value_type.clone())), + (value_type, _) => bail!(ErrorKind::BadEDNValuePair(value.clone(), value_type)), } } } diff --git a/db/src/tx.rs b/db/src/tx.rs index 0e280227..48a0ef8a 100644 --- a/db/src/tx.rs +++ b/db/src/tx.rs @@ -205,7 +205,7 @@ impl<'conn, 'a> Tx<'conn, 'a> { bail!(ErrorKind::NotYetImplemented(format!("Cannot resolve (lookup-ref {} {}) with attribute that is not :db/unique", lr_a, lookup_ref.v))) } - let lr_typed_value: TypedValue = self.schema.to_typed_value(&lookup_ref.v, &lr_attribute)?; + let lr_typed_value: TypedValue = self.schema.to_typed_value(&lookup_ref.v, lr_attribute.value_type)?; Ok(lookup_refs.intern((lr_a, lr_typed_value))) }; @@ -260,7 +260,7 @@ impl<'conn, 'a> Tx<'conn, 'a> { // Here is where we do schema-aware typechecking: we either assert that // the given value is in the attribute's value set, or (in limited // cases) coerce the value into the attribute's value set. - let typed_value: TypedValue = self.schema.to_typed_value(&v.without_spans(), &attribute)?; + let typed_value: TypedValue = self.schema.to_typed_value(&v.without_spans(), attribute.value_type)?; Either::Left(typed_value) } },