tantiny 0.3.3 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/Cargo.toml +9 -6
- data/README.md +118 -42
- data/bin/console +2 -3
- data/lib/tantiny/errors.rb +1 -1
- data/lib/tantiny/index.rb +29 -19
- data/lib/tantiny/query.rb +21 -16
- data/lib/tantiny/schema.rb +2 -2
- data/lib/tantiny/version.rb +1 -1
- data/lib/tantiny.rb +21 -10
- data/lib/tantiny.so +0 -0
- data/src/helpers.rs +71 -191
- data/src/index.rs +310 -197
- data/src/lib.rs +12 -9
- data/src/query.rs +246 -203
- data/src/tokenizer.rs +62 -75
- metadata +44 -43
- data/lib/.rbnext/3.0/tantiny/schema.rb +0 -53
- data/sig/tantiny/errors.rbs +0 -20
- data/sig/tantiny/helpers.rbs +0 -8
- data/sig/tantiny/index.rbs +0 -103
- data/sig/tantiny/query.rbs +0 -135
- data/sig/tantiny/schema.rbs +0 -26
- data/sig/tantiny/tokenizer.rbs +0 -25
- data/sig/tantiny/version.rbs +0 -3
- data/sig/tantiny.rbs +0 -5
data/src/helpers.rs
CHANGED
|
@@ -1,202 +1,82 @@
|
|
|
1
|
+
use magnus::{r_hash::ForEach, Error, RArray, RHash, Ruby, TryConvert, Value};
|
|
1
2
|
use std::collections::HashMap;
|
|
2
|
-
use rutie::{AnyException, Array, Exception, RString, Hash, Integer, Float, Boolean, Module};
|
|
3
|
-
use tantivy::tokenizer::Language;
|
|
4
|
-
|
|
5
|
-
// Macro dependencies:
|
|
6
|
-
pub(super) use paste::paste;
|
|
7
|
-
pub(super) use rutie::{class, wrappable_struct, AnyObject, VerifiedObject, VM, Object, Class};
|
|
8
|
-
|
|
9
|
-
pub(crate) fn namespace() -> Module {
|
|
10
|
-
Module::from_existing("Tantiny")
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
pub(crate) struct LanguageWrapper(pub(crate) Language);
|
|
14
|
-
|
|
15
|
-
impl std::str::FromStr for LanguageWrapper {
|
|
16
|
-
type Err = String;
|
|
17
|
-
|
|
18
|
-
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
19
|
-
match s {
|
|
20
|
-
"en" => Ok(LanguageWrapper(Language::English)),
|
|
21
|
-
"ar" => Ok(LanguageWrapper(Language::Arabic)),
|
|
22
|
-
"da" => Ok(LanguageWrapper(Language::Danish)),
|
|
23
|
-
"nl" => Ok(LanguageWrapper(Language::Dutch)),
|
|
24
|
-
"fi" => Ok(LanguageWrapper(Language::Finnish)),
|
|
25
|
-
"fr" => Ok(LanguageWrapper(Language::French)),
|
|
26
|
-
"de" => Ok(LanguageWrapper(Language::German)),
|
|
27
|
-
"el" => Ok(LanguageWrapper(Language::Greek)),
|
|
28
|
-
"hu" => Ok(LanguageWrapper(Language::Hungarian)),
|
|
29
|
-
"it" => Ok(LanguageWrapper(Language::Italian)),
|
|
30
|
-
"no" => Ok(LanguageWrapper(Language::Norwegian)),
|
|
31
|
-
"pt" => Ok(LanguageWrapper(Language::Portuguese)),
|
|
32
|
-
"ro" => Ok(LanguageWrapper(Language::Romanian)),
|
|
33
|
-
"ru" => Ok(LanguageWrapper(Language::Russian)),
|
|
34
|
-
"es" => Ok(LanguageWrapper(Language::Spanish)),
|
|
35
|
-
"sv" => Ok(LanguageWrapper(Language::Swedish)),
|
|
36
|
-
"ta" => Ok(LanguageWrapper(Language::Tamil)),
|
|
37
|
-
"tr" => Ok(LanguageWrapper(Language::Turkish)),
|
|
38
|
-
_ => Err(format!("Language '{}' is not supported.", s)),
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
pub(crate) trait TryUnwrap<T> {
|
|
44
|
-
fn try_unwrap(self) -> T;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
macro_rules! primitive_try_unwrap_impl {
|
|
48
|
-
( $ruby_type:ty, $type:ty ) => {
|
|
49
|
-
paste! {
|
|
50
|
-
impl TryUnwrap<$type> for $ruby_type {
|
|
51
|
-
fn try_unwrap(self) -> $type {
|
|
52
|
-
self.[<to_ $type:lower>]()
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
impl TryUnwrap<$type> for AnyObject {
|
|
57
|
-
fn try_unwrap(self) -> $type {
|
|
58
|
-
self.try_convert_to::<$ruby_type>()
|
|
59
|
-
.try_unwrap()
|
|
60
|
-
.[<to_ $type:lower>]()
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
primitive_try_unwrap_impl!(RString, String);
|
|
68
|
-
primitive_try_unwrap_impl!(Integer, i64);
|
|
69
|
-
primitive_try_unwrap_impl!(Float, f64);
|
|
70
|
-
primitive_try_unwrap_impl!(Boolean, bool);
|
|
71
|
-
|
|
72
|
-
impl<T> TryUnwrap<Vec<T>> for Array where
|
|
73
|
-
AnyObject: TryUnwrap<T>
|
|
74
|
-
{
|
|
75
|
-
fn try_unwrap(self) -> Vec<T> {
|
|
76
|
-
let mut vec = Vec::new();
|
|
77
|
-
|
|
78
|
-
for elem in self {
|
|
79
|
-
vec.push(elem.try_unwrap());
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
vec
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
impl<K, V> TryUnwrap<HashMap<K, V>> for Hash where
|
|
87
|
-
AnyObject: TryUnwrap<K> + TryUnwrap<V>,
|
|
88
|
-
K: Eq + std::hash::Hash
|
|
89
|
-
{
|
|
90
|
-
fn try_unwrap(self) -> HashMap<K, V> {
|
|
91
|
-
let mut hashmap = HashMap::new();
|
|
92
3
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
hashmap
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
impl<T, E> TryUnwrap<T> for Result<T, E>
|
|
4
|
+
/// Converts a Ruby hash to a HashMap where values can be either single values or arrays
|
|
5
|
+
pub fn hash_to_multivalue_map<K, V>(hash: RHash) -> Result<HashMap<K, Vec<V>>, Error>
|
|
102
6
|
where
|
|
103
|
-
|
|
7
|
+
K: std::cmp::Eq + std::hash::Hash + TryConvert,
|
|
8
|
+
V: TryConvert,
|
|
104
9
|
{
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
))
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
10
|
+
let ruby = unsafe { Ruby::get_unchecked() };
|
|
11
|
+
let mut map = HashMap::new();
|
|
12
|
+
|
|
13
|
+
hash.foreach(|key: Value, value: Value| {
|
|
14
|
+
let k: K = K::try_convert(key)
|
|
15
|
+
.map_err(|_| Error::new(ruby.exception_runtime_error(), "Key conversion failed"))?;
|
|
16
|
+
|
|
17
|
+
let values: Vec<V> = if let Ok(arr) = RArray::try_convert(value) {
|
|
18
|
+
// Value is an array, convert all elements
|
|
19
|
+
let mut vec = Vec::new();
|
|
20
|
+
for item_value in arr.into_iter() {
|
|
21
|
+
let v: V = V::try_convert(item_value).map_err(|_| {
|
|
22
|
+
Error::new(
|
|
23
|
+
ruby.exception_runtime_error(),
|
|
24
|
+
"Array element conversion failed",
|
|
25
|
+
)
|
|
26
|
+
})?;
|
|
27
|
+
vec.push(v);
|
|
28
|
+
}
|
|
29
|
+
vec
|
|
120
30
|
} else {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
)
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
31
|
+
// Value is a single value, wrap it in a Vec
|
|
32
|
+
let v: V = V::try_convert(value).map_err(|_| {
|
|
33
|
+
Error::new(ruby.exception_runtime_error(), "Value conversion failed")
|
|
34
|
+
})?;
|
|
35
|
+
vec![v]
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
map.insert(k, values);
|
|
39
|
+
Ok(ForEach::Continue)
|
|
40
|
+
})?;
|
|
41
|
+
|
|
42
|
+
Ok(map)
|
|
129
43
|
}
|
|
130
44
|
|
|
131
|
-
|
|
132
|
-
(
|
|
133
|
-
$param:ident: $type:ty,
|
|
134
|
-
$( $rest:tt )*
|
|
135
|
-
) => {
|
|
136
|
-
let _tmp = $param.map_err(|e| $crate::helpers::VM::raise_ex(e)).unwrap();
|
|
137
|
-
let $param = <_ as $crate::helpers::TryUnwrap<$type>>::try_unwrap(_tmp);
|
|
138
|
-
|
|
139
|
-
try_unwrap_params!($($rest)*)
|
|
140
|
-
};
|
|
141
|
-
(
|
|
142
|
-
$param:ident,
|
|
143
|
-
$( $rest:tt )*
|
|
144
|
-
) => {
|
|
145
|
-
let $param = $param.map_err(|e| $crate::helpers::VM::raise_ex(e)).unwrap();
|
|
146
|
-
|
|
147
|
-
try_unwrap_params!($($rest)*)
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
// Handle optional trailing commas.
|
|
151
|
-
( $param:ident: $type:ty ) => {
|
|
152
|
-
try_unwrap_params!($param: $type,)
|
|
153
|
-
};
|
|
154
|
-
( $param:ident ) => {
|
|
155
|
-
try_unwrap_params!($param,)
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
() => {}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
pub(crate) use try_unwrap_params;
|
|
162
|
-
|
|
163
|
-
macro_rules! scaffold {
|
|
164
|
-
( $ruby_type:ident, $type:ty, $klass:literal ) => {
|
|
165
|
-
$crate::helpers::class!($ruby_type);
|
|
166
|
-
|
|
167
|
-
// There is a bug in Rutie which prevents using this macro
|
|
168
|
-
// by resolving it by a full path, so the only workaround is:
|
|
169
|
-
use crate::helpers::wrappable_struct;
|
|
170
|
-
|
|
171
|
-
$crate::helpers::paste! {
|
|
172
|
-
wrappable_struct!(
|
|
173
|
-
$type,
|
|
174
|
-
[<$type Wrapper>],
|
|
175
|
-
[<$type:snake:upper _WRAPPER>]
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
pub(crate) fn klass() -> $crate::helpers::Class {
|
|
180
|
-
$crate::helpers::namespace().get_nested_class($klass)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
impl $crate::helpers::TryUnwrap<$ruby_type> for $crate::helpers::AnyObject {
|
|
184
|
-
fn try_unwrap(self) -> $ruby_type {
|
|
185
|
-
let result = self.try_convert_to::<$ruby_type>();
|
|
186
|
-
<_ as $crate::helpers::TryUnwrap<$ruby_type>>::try_unwrap(result)
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
impl $crate::helpers::VerifiedObject for $ruby_type {
|
|
191
|
-
fn is_correct_type<T: $crate::helpers::Object>(object: &T) -> bool {
|
|
192
|
-
object.class() == klass()
|
|
193
|
-
}
|
|
45
|
+
use tantivy::tokenizer::Language;
|
|
194
46
|
|
|
195
|
-
|
|
196
|
-
|
|
47
|
+
pub struct LanguageWrapper(pub Language);
|
|
48
|
+
|
|
49
|
+
impl TryFrom<String> for LanguageWrapper {
|
|
50
|
+
type Error = Error;
|
|
51
|
+
|
|
52
|
+
fn try_from(s: String) -> Result<Self, Self::Error> {
|
|
53
|
+
let lang = match s.as_str() {
|
|
54
|
+
"en" => Language::English,
|
|
55
|
+
"ar" => Language::Arabic,
|
|
56
|
+
"da" => Language::Danish,
|
|
57
|
+
"nl" => Language::Dutch,
|
|
58
|
+
"fi" => Language::Finnish,
|
|
59
|
+
"fr" => Language::French,
|
|
60
|
+
"de" => Language::German,
|
|
61
|
+
"el" => Language::Greek,
|
|
62
|
+
"hu" => Language::Hungarian,
|
|
63
|
+
"it" => Language::Italian,
|
|
64
|
+
"no" => Language::Norwegian,
|
|
65
|
+
"pt" => Language::Portuguese,
|
|
66
|
+
"ro" => Language::Romanian,
|
|
67
|
+
"ru" => Language::Russian,
|
|
68
|
+
"es" => Language::Spanish,
|
|
69
|
+
"sv" => Language::Swedish,
|
|
70
|
+
"ta" => Language::Tamil,
|
|
71
|
+
"tr" => Language::Turkish,
|
|
72
|
+
_ => {
|
|
73
|
+
let ruby = unsafe { Ruby::get_unchecked() };
|
|
74
|
+
return Err(Error::new(
|
|
75
|
+
ruby.exception_runtime_error(),
|
|
76
|
+
format!("Language '{}' is not supported.", s),
|
|
77
|
+
));
|
|
197
78
|
}
|
|
198
|
-
}
|
|
79
|
+
};
|
|
80
|
+
Ok(LanguageWrapper(lang))
|
|
199
81
|
}
|
|
200
82
|
}
|
|
201
|
-
|
|
202
|
-
pub(crate) use scaffold;
|