Skip to content

Commit e1ddb7e

Browse files
committed
Implement support for partial equality
1 parent b099125 commit e1ddb7e

File tree

18 files changed

+385
-17
lines changed

18 files changed

+385
-17
lines changed

crates/rune-core/src/protocol.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,20 +145,36 @@ impl Protocol {
145145
doc: ["Allows an indexing set operation to work."],
146146
};
147147

148-
/// Check two types for equality.
148+
/// Check two types for partial equality.
149+
pub const PARTIAL_EQ: Protocol = Protocol {
150+
name: "partial_eq",
151+
hash: 0x4b6bc4701445e318,
152+
repr: Some("if $value == b { }"),
153+
doc: ["Allows for partial equality operations to work."],
154+
};
155+
156+
/// Check two types for total equality.
149157
pub const EQ: Protocol = Protocol {
150158
name: "eq",
151159
hash: 0x418f5becbf885806,
152160
repr: Some("if $value == b { }"),
153161
doc: ["Allows an equality operation to work."],
154162
};
155163

156-
/// Perform an ordered comparison between two values.
164+
/// Perform an partial comparison between two values.
165+
pub const PARTIAL_CMP: Protocol = Protocol {
166+
name: "partial_cmp",
167+
hash: 0x8d4430991253343c,
168+
repr: Some("if $value < b { }"),
169+
doc: ["Allows for partial ordering to work."],
170+
};
171+
172+
/// Perform an total comparison between two values.
157173
pub const CMP: Protocol = Protocol {
158174
name: "cmp",
159175
hash: 0x240f1b75466cd1a3,
160176
repr: Some("if $value < b { }"),
161-
doc: ["Allows for ordering operations to work."],
177+
doc: ["Allows for total ordering to work."],
162178
};
163179

164180
/// The function to implement for the addition operation.

crates/rune/src/modules/cmp.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ pub fn module() -> Result<Module, ContextError> {
4545
.constructor(|| Ordering::Greater)?
4646
.docs(["An ordering where a compared value is greater than another."]);
4747

48+
module.associated_function(Protocol::PARTIAL_EQ, |lhs: Ordering, rhs: Ordering| {
49+
lhs == rhs
50+
})?;
4851
module.associated_function(Protocol::EQ, |lhs: Ordering, rhs: Ordering| lhs == rhs)?;
4952
Ok(module)
5053
}

crates/rune/src/modules/collections/hash_map.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub(super) fn setup(module: &mut Module) -> Result<(), ContextError> {
2828
module.associated_function(Protocol::INDEX_SET, HashMap::index_set)?;
2929
module.associated_function(Protocol::INDEX_GET, HashMap::index_get)?;
3030
module.associated_function(Protocol::STRING_DEBUG, HashMap::string_debug)?;
31+
module.associated_function(Protocol::PARTIAL_EQ, HashMap::partial_eq)?;
3132
module.associated_function(Protocol::EQ, HashMap::eq)?;
3233
Ok(())
3334
}
@@ -347,6 +348,24 @@ impl HashMap {
347348
write!(s, "{:?}", self.map)
348349
}
349350

351+
fn partial_eq(&self, other: &Self) -> VmResult<bool> {
352+
if self.map.len() != other.map.len() {
353+
return VmResult::Ok(false);
354+
}
355+
356+
for (k, v) in self.map.iter() {
357+
let Some(v2) = other.map.get(k) else {
358+
return VmResult::Ok(false);
359+
};
360+
361+
if !vm_try!(Value::partial_eq(v, v2)) {
362+
return VmResult::Ok(false);
363+
}
364+
}
365+
366+
VmResult::Ok(true)
367+
}
368+
350369
fn eq(&self, other: &Self) -> VmResult<bool> {
351370
if self.map.len() != other.map.len() {
352371
return VmResult::Ok(false);

crates/rune/src/modules/collections/hash_set.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub(super) fn setup(module: &mut Module) -> Result<(), ContextError> {
2828
module.function_meta(from)?;
2929
module.associated_function(Protocol::INTO_ITER, HashSet::__rune_fn__iter)?;
3030
module.associated_function(Protocol::STRING_DEBUG, HashSet::string_debug)?;
31+
module.associated_function(Protocol::PARTIAL_EQ, HashSet::partial_eq)?;
3132
module.associated_function(Protocol::EQ, HashSet::eq)?;
3233
Ok(())
3334
}
@@ -332,6 +333,10 @@ impl HashSet {
332333
VmResult::Ok(HashSet { set })
333334
}
334335

336+
fn partial_eq(&self, other: &Self) -> bool {
337+
self.set == other.set
338+
}
339+
335340
fn eq(&self, other: &Self) -> bool {
336341
self.set == other.set
337342
}

crates/rune/src/modules/collections/vec_deque.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ pub(super) fn setup(m: &mut Module) -> Result<(), ContextError> {
5555
m.associated_function(Protocol::INDEX_SET, VecDeque::set)?;
5656
m.associated_function(Protocol::INTO_ITER, VecDeque::__rune_fn__iter)?;
5757
m.associated_function(Protocol::STRING_DEBUG, VecDeque::string_debug)?;
58+
m.associated_function(Protocol::PARTIAL_EQ, VecDeque::partial_eq)?;
5859
m.associated_function(Protocol::EQ, VecDeque::eq)?;
5960
m.associated_function(Protocol::CMP, VecDeque::cmp)?;
6061
Ok(())
@@ -507,6 +508,26 @@ impl VecDeque {
507508
write!(s, "{:?}", self.inner)
508509
}
509510

511+
fn partial_eq(this: &VecDeque, other: Value) -> VmResult<bool> {
512+
let mut other = vm_try!(other.into_iter());
513+
514+
for a in &this.inner {
515+
let Some(b) = vm_try!(other.next()) else {
516+
return VmResult::Ok(false);
517+
};
518+
519+
if !vm_try!(Value::partial_eq(a, &b)) {
520+
return VmResult::Ok(false);
521+
}
522+
}
523+
524+
if vm_try!(other.next()).is_some() {
525+
return VmResult::Ok(false);
526+
}
527+
528+
VmResult::Ok(true)
529+
}
530+
510531
fn eq(this: &VecDeque, other: Value) -> VmResult<bool> {
511532
let mut other = vm_try!(other.into_iter());
512533

crates/rune/src/modules/vec.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub fn module() -> Result<Module, ContextError> {
4848
m.function_meta(sort_string)?;
4949
m.associated_function(Protocol::INTO_ITER, Vec::iter_ref)?;
5050
m.associated_function(Protocol::INDEX_SET, Vec::set)?;
51+
m.associated_function(Protocol::PARTIAL_EQ, partial_eq)?;
5152
m.associated_function(Protocol::EQ, eq)?;
5253
Ok(m)
5354
}
@@ -523,6 +524,26 @@ fn clone(this: &Vec) -> Vec {
523524
this.clone()
524525
}
525526

527+
fn partial_eq(this: &Vec, other: Value) -> VmResult<bool> {
528+
let mut other = vm_try!(other.into_iter());
529+
530+
for a in this.as_slice() {
531+
let Some(b) = vm_try!(other.next()) else {
532+
return VmResult::Ok(false);
533+
};
534+
535+
if !vm_try!(Value::partial_eq(a, &b)) {
536+
return VmResult::Ok(false);
537+
}
538+
}
539+
540+
if vm_try!(other.next()).is_some() {
541+
return VmResult::Ok(false);
542+
}
543+
544+
VmResult::Ok(true)
545+
}
546+
526547
fn eq(this: &Vec, other: Value) -> VmResult<bool> {
527548
let mut other = vm_try!(other.into_iter());
528549

crates/rune/src/runtime/object.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,28 @@ impl Object {
294294
Iterator::from("std::object::Iter", self.clone().into_iter())
295295
}
296296

297+
pub(crate) fn partial_eq_with(
298+
a: &Self,
299+
b: &Self,
300+
caller: &mut impl ProtocolCaller,
301+
) -> VmResult<bool> {
302+
if a.inner.len() != b.inner.len() {
303+
return VmResult::Ok(false);
304+
}
305+
306+
for (key, a) in a.inner.iter() {
307+
let Some(b) = b.inner.get(key) else {
308+
return VmResult::Ok(false);
309+
};
310+
311+
if !vm_try!(Value::partial_eq_with(a, b, caller)) {
312+
return VmResult::Ok(false);
313+
}
314+
}
315+
316+
VmResult::Ok(true)
317+
}
318+
297319
pub(crate) fn eq_with(a: &Self, b: &Self, caller: &mut impl ProtocolCaller) -> VmResult<bool> {
298320
if a.inner.len() != b.inner.len() {
299321
return VmResult::Ok(false);

crates/rune/src/runtime/range.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,16 +75,24 @@ impl Range {
7575
}
7676
}
7777

78-
pub(crate) fn eq_with(a: &Self, b: &Self, caller: &mut impl ProtocolCaller) -> VmResult<bool> {
79-
if !vm_try!(Value::eq_with(&a.start, &b.start, caller)) {
78+
pub(crate) fn partial_eq_with(
79+
a: &Self,
80+
b: &Self,
81+
caller: &mut impl ProtocolCaller,
82+
) -> VmResult<bool> {
83+
if !vm_try!(Value::partial_eq_with(&a.start, &b.start, caller)) {
8084
return VmResult::Ok(false);
8185
}
8286

83-
if !vm_try!(Value::eq_with(&a.end, &b.end, caller)) {
87+
Value::partial_eq_with(&a.end, &b.end, caller)
88+
}
89+
90+
pub(crate) fn eq_with(a: &Self, b: &Self, caller: &mut impl ProtocolCaller) -> VmResult<bool> {
91+
if !vm_try!(Value::eq_with(&a.start, &b.start, caller)) {
8492
return VmResult::Ok(false);
8593
}
8694

87-
VmResult::Ok(true)
95+
Value::eq_with(&a.end, &b.end, caller)
8896
}
8997

9098
pub(crate) fn cmp_with(

crates/rune/src/runtime/range_from.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ impl RangeFrom {
6565
}
6666
}
6767

68+
pub(crate) fn partial_eq_with(
69+
a: &Self,
70+
b: &Self,
71+
caller: &mut impl ProtocolCaller,
72+
) -> VmResult<bool> {
73+
VmResult::Ok(vm_try!(Value::partial_eq_with(&a.start, &b.start, caller)))
74+
}
75+
6876
pub(crate) fn eq_with(a: &Self, b: &Self, caller: &mut impl ProtocolCaller) -> VmResult<bool> {
6977
VmResult::Ok(vm_try!(Value::eq_with(&a.start, &b.start, caller)))
7078
}

crates/rune/src/runtime/range_full.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ impl RangeFull {
2626
Self
2727
}
2828

29+
pub(crate) fn partial_eq_with(
30+
_: &Self,
31+
_: &Self,
32+
_: &mut impl ProtocolCaller,
33+
) -> VmResult<bool> {
34+
VmResult::Ok(true)
35+
}
36+
2937
pub(crate) fn eq_with(_: &Self, _: &Self, _: &mut impl ProtocolCaller) -> VmResult<bool> {
3038
VmResult::Ok(true)
3139
}

0 commit comments

Comments
 (0)