Pre: Use ValueType rather than Attribute to convert edn::Value to TypedValue.
This is expedient now, but might require work in the future to achieve better error messages.
This commit is contained in:
parent
2650fe163d
commit
05129cefbb
2 changed files with 20 additions and 18 deletions
|
@ -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<TypedValue>;
|
||||
/// 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<TypedValue>;
|
||||
}
|
||||
|
||||
impl SchemaTypeChecking for Schema {
|
||||
fn to_typed_value(&self, value: &edn::Value, attribute: &Attribute) -> Result<TypedValue> {
|
||||
// TODO: encapsulate entid-ident-attribute for better error messages.
|
||||
fn to_typed_value(&self, value: &edn::Value, value_type: ValueType) -> Result<TypedValue> {
|
||||
// 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)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue