diff options
author | SoniEx2 <endermoneymod@gmail.com> | 2022-08-06 15:06:18 -0300 |
---|---|---|
committer | SoniEx2 <endermoneymod@gmail.com> | 2022-08-06 15:06:18 -0300 |
commit | f24123f943abaebffd098a12069bcca62181f862 (patch) | |
tree | dd36cc3cafc0ec71fc388b610ec127bb53b657bf /src | |
parent | a8778ff35bde88bb63d9fec769edf66e68d7969e (diff) |
Fix predicates
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 29 | ||||
-rw-r--r-- | src/pattern.rs | 47 | ||||
-rw-r--r-- | src/vm.rs | 9 | ||||
-rw-r--r-- | src/vm/de.rs | 6 |
4 files changed, 85 insertions, 6 deletions
diff --git a/src/lib.rs b/src/lib.rs index 8fa727f..a3a6e1e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -106,15 +106,34 @@ mod vm; pub use pattern::Pattern; /// A predicate. -pub type Predicate = dyn (for<'x, 'de, 'a> Fn( - &'x (dyn 'a + erased_serde::Deserializer<'de>) +pub type Predicate = dyn (Fn( + &mut dyn erased_serde::Deserializer<> ) -> bool) + Send + Sync; -/// Helper to build predicates because HRTB inference is the worst. +/// Helper to build predicates because closure inference is the worst. +/// +/// # Examples +/// +/// This doesn't work: +/// +/// ```rust compile_fail +/// use serde::Deserialize; +/// use datafu::Predicate; +/// +/// let x = Box::new(|v| String::deserialize(v).is_ok()) as Box<Predicate>; +/// ``` +/// +/// But this does: +/// +/// ```rust +/// use serde::Deserialize; +/// +/// let x = datafu::pred(|v| String::deserialize(v).is_ok()); +/// ``` pub fn pred<F>(f: F) -> Box<Predicate> where - F: (for<'x, 'de, 'a> Fn( - &'x (dyn 'a + erased_serde::Deserializer<'de>) + F: (Fn( + &mut dyn erased_serde::Deserializer<> ) -> bool) + Send + Sync + 'static, { Box::new(f) diff --git a/src/pattern.rs b/src/pattern.rs index 3a8c91f..2e69714 100644 --- a/src/pattern.rs +++ b/src/pattern.rs @@ -1,6 +1,8 @@ // Copyright (C) 2021-2022 Soni L. // SPDX-License-Identifier: MIT OR Apache-2.0 +//! Datafu Patterns. + use std::borrow::Borrow; use std::collections::BTreeMap; @@ -15,12 +17,57 @@ use crate::parser::parse; use crate::vm::PatternConstants; //use crate::vm::MAX_CALLS; +/// A compiled Datafu pattern. +/// +/// # Examples +/// +/// ``` +/// use datafu::Pattern; +/// +/// let pattern = Pattern::<()>::compile::<&str, &str>( +/// "->'hello'", +/// None, None +/// ).expect("failed to compile pattern"); +/// ``` pub struct Pattern<O: Serialize> { consts: PatternConstants<O>, } impl<O: Serialize> Pattern<O> { /// Compiles the input into a pattern. + /// + /// # Examples + /// + /// ``` + /// use datafu::Pattern; + /// use serde::Deserialize; + /// use charx; + /// + /// let preds = vec![ + /// ("dict", datafu::pred(|v| { todo!() })), + /// ("str", datafu::pred(|v| { String::deserialize(v).is_ok() })), + /// ("commit", datafu::pred(|v| { + /// if let Ok(v) = String::deserialize(v) { + /// v.len() == 40 && v.trim_start_matches( + /// charx::is_ascii_hexdigit + /// ).is_empty() + /// } else { + /// false + /// } + /// })), + /// ("uri", datafu::pred(|v| { todo!() })), + /// ("bool", datafu::pred(|v| { todo!() })), + /// ].into_iter().collect(); + /// let pattern = Pattern::<()>::compile::<&str, &str>(" + /// ->'projects':$dict + /// ->commit[:?$str:?$commit]:?$dict + /// ->url[:?$str:?$uri]:?$dict + /// ->branch:?$dict + /// (->active'active'?:?$bool) + /// (->federate'federate'?:?$bool)?", + /// Some(preds), None + /// ).expect("failed to compile pattern"); + /// ``` pub fn compile<'s, PKey, OKey>( input: &'s str, preds: Option<BTreeMap<PKey, Box<Predicate>>>, diff --git a/src/vm.rs b/src/vm.rs index 6bcbf70..ac5c95d 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -1,17 +1,24 @@ // Copyright (C) 2021-2022 Soni L. // SPDX-License-Identifier: MIT OR Apache-2.0 +//! The Datafu Virtual Machine. +//! +//! This is the stuff that actually matches the pattern. + use regex::Regex; use serde::Serialize; use crate::Predicate; //use crate::errors::MatchError; +mod de; + +/// Max depth for VM/serde recursion. pub(crate) const MAX_CALLS: usize = 250; //type Matches<'a, 'b, T> = BTreeMap<&'a str, KVPair<'b, T>>; -// TODO: use a builder for this? +// maybe we should use a builder for this? /// The constant pool for a pattern. pub(crate) struct PatternConstants<O: Serialize> { // last proto is implicitly the whole pattern. diff --git a/src/vm/de.rs b/src/vm/de.rs new file mode 100644 index 0000000..7039ea9 --- /dev/null +++ b/src/vm/de.rs @@ -0,0 +1,6 @@ +// Copyright (C) 2022 Soni L. +// SPDX-License-Identifier: MIT OR Apache-2.0 + +use crate::vm; + + |