Type compatibility

For now, types can be used like strings in operations to prevent breakage of many packages. Hopefully, we can get rid of this in the future.
This commit is contained in:
Laurenz 2023-09-11 17:26:56 +02:00
parent 3a979e88da
commit 2dc000daeb
3 changed files with 36 additions and 0 deletions

View File

@ -34,6 +34,11 @@ pub fn join(lhs: Value, rhs: Value) -> StrResult<Value> {
(Symbol(a), Content(b)) => Content(item!(text)(a.get().into()) + b),
(Array(a), Array(b)) => Array(a + b),
(Dict(a), Dict(b)) => Dict(a + b),
// Type compatibility.
(Type(a), Str(b)) => Str(format_str!("{a}{b}")),
(Str(a), Type(b)) => Str(format_str!("{a}{b}")),
(a, b) => mismatch!("cannot join {} with {}", a, b),
})
}
@ -119,6 +124,10 @@ pub fn add(lhs: Value, rhs: Value) -> StrResult<Value> {
(Datetime(a), Duration(b)) => Datetime(a + b),
(Duration(a), Datetime(b)) => Datetime(b + a),
// Type compatibility.
(Type(a), Str(b)) => Str(format_str!("{a}{b}")),
(Str(a), Type(b)) => Str(format_str!("{a}{b}")),
(Dyn(a), Dyn(b)) => {
// Alignments can be summed.
if let (Some(&a), Some(&b)) = (a.downcast::<Align>(), b.downcast::<Align>()) {
@ -380,6 +389,10 @@ pub fn equal(lhs: &Value, rhs: &Value) -> bool {
(&Relative(a), &Length(b)) => a.abs == b && a.rel.is_zero(),
(&Relative(a), &Ratio(b)) => a.rel == b && a.abs.is_zero(),
// Type compatibility.
(Type(a), Str(b)) => a.compat_name() == b.as_str(),
(Str(a), Type(b)) => a.as_str() == b.compat_name(),
_ => false,
}
}
@ -449,6 +462,11 @@ pub fn contains(lhs: &Value, rhs: &Value) -> Option<bool> {
(Dyn(a), Str(b)) => a.downcast::<Regex>().map(|regex| regex.is_match(b)),
(Str(a), Dict(b)) => Some(b.contains(a)),
(a, Array(b)) => Some(b.contains(a.clone())),
// Type compatibility.
(Type(a), Str(b)) => Some(b.as_str().contains(a.compat_name())),
(Type(a), Dict(b)) => Some(b.contains(a.compat_name())),
_ => Option::None,
}
}

View File

@ -80,6 +80,14 @@ impl Type {
}
}
// Type compatibility.
impl Type {
/// The type's backwards-compatible name.
pub fn compat_name(&self) -> &str {
self.long_name()
}
}
#[scope]
impl Type {
/// Determines a value's type.

View File

@ -0,0 +1,10 @@
// Test compatibility between types and strings.
// Ref: false
---
#test(type(10), int)
#test(type(10), "integer")
#test("is " + type(10), "is integer")
#test(int in ("integer", "string"), true)
#test(int in "integers or strings", true)
#test(str in "integers or strings", true)