/* * Datafu - Rust library for extracting data from object graphs. * Copyright (C) 2021 Soni L. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ pub mod errors; mod parser; mod pattern; mod vm; pub use pattern::Pattern; // TODO replace with GATs /// 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 U. Own(U), } impl<'b, T, U> PartialEq for RefOwn<'b, T, U> where T: ?Sized + PartialEq + PartialEq + PartialEq, U: PartialEq + PartialEq + PartialEq, str: PartialEq + PartialEq + PartialEq { 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: ?Sized, U: Clone> Clone for RefOwn<'b, T, U> { fn clone(&self) -> Self { match self { RefOwn::Ref(r) => RefOwn::Ref(r), RefOwn::Str(r) => RefOwn::Str(r), RefOwn::Own(v) => RefOwn::Own(v.clone()), } } } pub type KVPair<'b, T> = (RefOwn<'b, ::Ref, ::Own>, RefOwn<'b, ::Ref, ::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 { /// The borrowed type. type Ref: ?Sized; // TODO replace with GATs. // TODO potentially relax with Clone? /// 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: RefOwn<'b, Self::Ref, Self::Own> ) -> Option> + 'b>> { // TODO remove these default impls that only exist for testing purposes let x = None; Some(Box::new(x.into_iter())) } /// 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: RefOwn<'b, Self::Ref, Self::Own>, key: RefOwn<'a, Self::Ref, Self::Own> ) -> Option>> { // TODO remove these default impls that only exist for testing purposes Some(None) } // TODO replace with GATs + newtypes /// Returns whether two keys/values are the same/equivalent. This must provide /// 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: RefOwn<'_, Self::Ref, Self::Own>, right: RefOwn<'_, Self::Ref, Self::Own> ) -> bool; } // TODO type Predicate = dyn (Fn(RefOwn<::Ref, ::Own>) -> bool) + Send + Sync;