From 22f3c3a9e3cd14ad6fe05c647ddb81017336cd62 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sat, 25 Aug 2018 11:18:59 -0700 Subject: [PATCH] [types] Value equivalence via PartialEq! --- types/src/object.rs | 20 +++++++++++++++++++- types/src/pair.rs | 17 +++++++++++++++++ types/src/sym.rs | 16 ++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/types/src/object.rs b/types/src/object.rs index 3c9baf3..76735d9 100644 --- a/types/src/object.rs +++ b/types/src/object.rs @@ -13,6 +13,7 @@ //! available types in Scheme. These predicates are implemented as `is_*` //! methods in a bunch of `Is*` traits defined below. +use std::ops::Deref; use std::mem; use std::any::Any; use std::fmt; @@ -26,7 +27,8 @@ pub enum Obj { pub trait Object: fmt::Debug + - fmt::Display + fmt::Display + + PartialEq { /// Cast this Object to an Any. fn as_any(&self) -> &Any; @@ -52,6 +54,13 @@ impl Obj { Obj::Ptr(obj) => obj.as_any().downcast_ref::() } } + + pub fn is_null(&self) -> bool { + match self { + Obj::Null => true, + _ => false + } + } } impl fmt::Display for Obj { @@ -63,6 +72,15 @@ impl fmt::Display for Obj { } } +impl PartialEq for Obj { + fn eq(&self, rhs: &Self) -> bool { + match self { + Obj::Null => rhs.is_null(), + Obj::Ptr(ref inner) => inner.deref() == rhs + } + } +} + //#[derive(Debug, PartialEq)] //pub enum Object { // ByteVector(Vec), diff --git a/types/src/pair.rs b/types/src/pair.rs index b142c25..a0d7d87 100644 --- a/types/src/pair.rs +++ b/types/src/pair.rs @@ -52,6 +52,23 @@ impl fmt::Display for Pair { } } +impl PartialEq for Pair { + fn eq(&self, rhs: &Obj) -> bool { + match rhs { + Obj::Null => false, + Obj::Ptr(ref rhs) => { + if let Some(rhs_pair) = rhs.as_pair() { + let car_eq = self.car == rhs_pair.car; + let cdr_eq = self.cdr == rhs_pair.cdr; + car_eq && cdr_eq + } else { + false + } + } + } + } +} + #[cfg(test)] mod tests { use super::Pair; diff --git a/types/src/sym.rs b/types/src/sym.rs index 3c47599..c318e08 100644 --- a/types/src/sym.rs +++ b/types/src/sym.rs @@ -3,6 +3,7 @@ */ use std::any::Any; +use std::ops::Deref; use std::fmt; use object::Object; use super::*; @@ -33,6 +34,21 @@ impl fmt::Display for Sym { } } +impl PartialEq for Sym { + fn eq(&self, rhs: &Obj) -> bool { + match rhs { + Obj::Null => false, + Obj::Ptr(ref inner) => { + if let Some(rhs_sym) = inner.deref().as_sym() { + self.0 == rhs_sym.0 + } else { + false + } + } + } + } +} + #[cfg(test)] mod tests { use super::Sym;