diff options
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 68 |
1 files changed, 47 insertions, 21 deletions
diff --git a/src/lib.rs b/src/lib.rs index 08609ab..b5d7bc6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,47 +6,73 @@ mod vm; pub use pattern::Pattern; // TODO replace with GATs -/// The key returned from pairs and get. -pub enum Key<'b, T, U> { - /// Reference. +/// A borrowed or owned value of various types. +pub enum RefOwn<'b, T: ?Sized, U> { + /// Borrowed T. Ref(&'b T), /// Borrowed string. Str(&'b str), - /// Owned types. + /// Owned U. Own(U), } -impl<'b, T, U: Copy> Copy for Key<'b, T, U> { +impl<'b, T, U> PartialEq for RefOwn<'b, T, U> +where + T: ?Sized + PartialEq<T> + PartialEq<U> + PartialEq<str>, + U: PartialEq<T> + PartialEq<U> + PartialEq<str>, + str: PartialEq<T> + PartialEq<U> + PartialEq<str> +{ + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (RefOwn::Ref(l), RefOwn::Ref(r)) => l.eq(r), + (RefOwn::Own(l), RefOwn::Own(r)) => l.eq(r), + (RefOwn::Str(l), RefOwn::Str(r)) => l.eq(r), + (RefOwn::Ref(l), RefOwn::Own(r)) => PartialEq::eq(*l, r), + (RefOwn::Own(l), RefOwn::Str(r)) => PartialEq::eq(l, *r), + (RefOwn::Str(l), RefOwn::Ref(r)) => l.eq(r), + (RefOwn::Ref(l), RefOwn::Str(r)) => l.eq(r), + (RefOwn::Own(l), RefOwn::Ref(r)) => PartialEq::eq(l, *r), + (RefOwn::Str(l), RefOwn::Own(r)) => PartialEq::eq(*l, r), + } + } +} + +impl<'b, T: ?Sized, U: Copy> Copy for RefOwn<'b, T, U> { } -impl<'b, T, U: Clone> Clone for Key<'b, T, U> { +impl<'b, T: ?Sized, U: Clone> Clone for RefOwn<'b, T, U> { fn clone(&self) -> Self { match self { - Key::Ref(r) => Key::Ref(r), - Key::Str(r) => Key::Str(r), - Key::Own(v) => Key::Own(v.clone()), + RefOwn::Ref(r) => RefOwn::Ref(r), + RefOwn::Str(r) => RefOwn::Str(r), + RefOwn::Own(v) => RefOwn::Own(v.clone()), } } } -pub type KVPair<'b, T> = (Key<'b, <T as PatternTypes>::Value, <T as PatternTypes>::OwnKey>, &'b <T as PatternTypes>::Value); +pub type KVPair<'b, T> = (RefOwn<'b, <T as PatternTypes>::Ref, <T as PatternTypes>::Own>, RefOwn<'b, <T as PatternTypes>::Ref, <T as PatternTypes>::Own>); + +impl<'b, T, U> From<&'b T> for RefOwn<'b, T, U> { + fn from(x: &'b T) -> RefOwn<'b, T, U> { + RefOwn::Ref(x) + } +} // TODO investigate if this should be PatternTypes: Default /// Defines the types and operations used for matching. pub trait PatternTypes { - // TODO investigate Value: ?Sized - /// The value type. - type Value; + /// The borrowed type. + type Ref: ?Sized; // TODO replace with GATs. // TODO potentially relax with Clone? - /// The owned key type. May be uninhabited. - type OwnKey: Copy + 'static; + /// The owned type. + type Own: Copy + 'static; /// Returns an iterator over key-value pairs contained within an item, or /// None if this operation is unsupported for the given value. fn pairs<'b>( - item: &'b Self::Value + item: RefOwn<'b, Self::Ref, Self::Own> ) -> Option<Box<dyn Iterator<Item=KVPair<'b, Self>> + 'b>> { // TODO remove these default impls that only exist for testing purposes let x = None; @@ -56,8 +82,8 @@ pub trait PatternTypes { /// Returns an optional key-value pair keyed by the given key, or None if /// this operation is unsupported for the given value. fn get<'a, 'b>( - item: &'b Self::Value, - key: Key<'a, Self::Value, Self::OwnKey> + item: RefOwn<'b, Self::Ref, Self::Own>, + key: RefOwn<'a, Self::Ref, Self::Own> ) -> Option<Option<KVPair<'b, Self>>> { // TODO remove these default impls that only exist for testing purposes Some(None) @@ -68,10 +94,10 @@ pub trait PatternTypes { /// the same guarantees as PartialEq. In fact, this is a replacement for /// PartialEq for cases where it's not possible to just use PartialEq. fn matches( - left: Key<'_, Self::Value, Self::OwnKey>, - right: Key<'_, Self::Value, Self::OwnKey> + left: RefOwn<'_, Self::Ref, Self::Own>, + right: RefOwn<'_, Self::Ref, Self::Own> ) -> bool; } // TODO -type Predicate<T> = dyn (Fn(&<T as PatternTypes>::Value) -> bool) + Send + Sync; +type Predicate<T> = dyn (Fn(RefOwn<<T as PatternTypes>::Ref, <T as PatternTypes>::Own>) -> bool) + Send + Sync; |