From f2c32a6f27eb67194672f4ae7051714bba2eae85 Mon Sep 17 00:00:00 2001 From: SoniEx2 Date: Sun, 24 Jan 2021 16:16:13 -0300 Subject: Clean up public API --- src/lib.rs | 68 ++++++++++++++++++++++++++++++++++++++++------------------ src/parser.rs | 2 +- src/pattern.rs | 9 ++++---- src/vm.rs | 33 ++++++++++++++++++++++------ 4 files changed, 79 insertions(+), 33 deletions(-) (limited to 'src') 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 + 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, 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, ::Value, ::OwnKey>, &'b ::Value); +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 { - // 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> + '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>> { // 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 = dyn (Fn(&::Value) -> bool) + Send + Sync; +type Predicate = dyn (Fn(RefOwn<::Ref, ::Own>) -> bool) + Send + Sync; diff --git a/src/parser.rs b/src/parser.rs index 0a7d858..17c0529 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -5,6 +5,6 @@ use crate::errors::PatternError; use crate::vm::PatternConstants; //use crate::vm::PatternElement; -pub(crate) fn parse(s: &str) -> Result, PatternError> { +pub(crate) fn parse(s: &str, defs: Option<()>/*TODO*/) -> Result, PatternError> { unimplemented!() } diff --git a/src/pattern.rs b/src/pattern.rs index 0368a88..2b99163 100644 --- a/src/pattern.rs +++ b/src/pattern.rs @@ -1,4 +1,5 @@ use crate::PatternTypes; +use crate::RefOwn; use crate::errors::PatternError; use crate::parser::parse; use crate::vm::Matcher; @@ -10,16 +11,16 @@ pub struct Pattern { } impl Pattern { - pub fn compile(s: &str) -> Result { + pub fn compile(s: &str, defs: Option<()>/*TODO*/) -> Result { Ok(Self { - consts: parse(s)? + consts: parse(s, defs)? }) } pub fn attempt_match<'a, 'b>( &'a self, - value: &'b T::Value + value: impl Into> ) -> Matcher<'a, 'b, T> { - Matcher::new(value, &self.consts, self.consts.protos.len() - 1, MAX_CALLS).ok().expect("datafu internal error: MAX_CALLS must not be 0") + Matcher::new(value.into(), &self.consts, self.consts.protos.len() - 1, MAX_CALLS).ok().expect("datafu internal error: MAX_CALLS must not be 0") } } diff --git a/src/vm.rs b/src/vm.rs index 5b27a36..44675f3 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -1,4 +1,23 @@ +/* + * This file is part of Datafu + * 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 . + */ + use crate::KVPair; +use crate::RefOwn; use crate::PatternTypes; use crate::Predicate; use crate::errors::MatchError; @@ -23,7 +42,7 @@ pub(crate) struct PatternConstants { // NOTE these are part of the constant pool and so have lifetime analogous // to 'a (consistently used to indicate constant pool lifetime) when used // elsewhere. In particular, they can't be yielded by the iterator. - pub(crate) defs: Vec, + pub(crate) defs: Vec, } /// A pattern element. @@ -49,7 +68,7 @@ impl Clone for PatternElement { } struct Frame<'a, 'b, T: PatternTypes> { - obj: &'b T::Value, + obj: RefOwn<'b, T::Ref, T::Own>, ops: &'a Vec>, iar: Option, depth: usize, @@ -97,7 +116,7 @@ enum HolderState<'a, 'b, T: PatternTypes> { EmptyKey, EmptySubtree, Key(KVPair<'b, T>), - Subtree(Matches<'a, 'b, T>, &'b T::Value), + Subtree(Matches<'a, 'b, T>, RefOwn<'b, T::Ref, T::Own>), } impl<'a, 'b, T: PatternTypes> Clone for HolderState<'a, 'b, T> { @@ -120,8 +139,8 @@ impl<'a, 'b, T: PatternTypes> HolderState<'a, 'b, T> { matches!(self, HolderState::EmptySubtree | HolderState::Subtree {..}) } - fn value(&self) -> Option<&'b T::Value> { - match self { + fn value(&self) -> Option> { + match *self { HolderState::Key((_, value)) => Some(value), HolderState::Subtree(_, value) => Some(value), _ => None @@ -136,7 +155,7 @@ impl<'a, 'b, T: PatternTypes> HolderState<'a, 'b, T> { struct Holder<'a, 'b, T: PatternTypes> { name: Option<&'a str>, value: HolderState<'a, 'b, T>, - parent: Option<&'b T::Value>, + parent: Option>, iterator: Box> + 'b>, filters: Vec Fn(&'c mut HolderState<'a, 'b, T>) + 'a>>, } @@ -176,7 +195,7 @@ pub struct Matcher<'a, 'b, T: PatternTypes> { } impl<'a, 'b, T: PatternTypes> Matcher<'a, 'b, T> { - pub(crate) fn new(obj: &'b T::Value, defs: &'a PatternConstants, proto: usize, rlimit: usize) -> Result { + pub(crate) fn new(obj: RefOwn<'b, T::Ref, T::Own>, defs: &'a PatternConstants, proto: usize, rlimit: usize) -> Result { let depth = rlimit.checked_sub(1).ok_or(MatchError::StackOverflow)?; let ops: &Vec<_> = &defs.protos[proto]; Ok(Self { -- cgit 1.4.1