1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
/*
* 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 <https://www.gnu.org/licenses/>.
*/
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<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: ?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, <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 {
/// 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<Box<dyn Iterator<Item=KVPair<'b, Self>> + '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<Option<KVPair<'b, Self>>> {
// 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<T> = dyn (Fn(RefOwn<<T as PatternTypes>::Ref, <T as PatternTypes>::Own>) -> bool) + Send + Sync;
|