diff --git a/Cargo.lock b/Cargo.lock index e6325ae4..44fac58d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,12 +73,6 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.4.1" @@ -450,9 +444,9 @@ dependencies = [ [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "htmlescape" @@ -567,16 +561,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" -[[package]] -name = "lock_api" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" -dependencies = [ - "autocfg", - "scopeguard", -] - [[package]] name = "log" version = "0.4.20" @@ -690,29 +674,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.48.5", -] - [[package]] name = "pin-project-lite" version = "0.2.13" @@ -770,33 +731,23 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.21.2" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e00b96a521718e08e03b1a622f01c8a8deb50719335de3f60b3b3950f069d8" +checksum = "e5203598f366b11a02b13aa20cab591229ff0a89fd121a308a5df751d5fc9219" dependencies = [ "cfg-if", "chrono", "indoc", "libc", "memoffset", - "parking_lot", + "once_cell", "portable-atomic", - "pyo3-build-config 0.21.2", + "pyo3-build-config", "pyo3-ffi", "pyo3-macros", "unindent", ] -[[package]] -name = "pyo3-build-config" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7883df5835fafdad87c0d888b266c8ec0f4c9ca48a5bed6bbb592e8dedee1b50" -dependencies = [ - "once_cell", - "target-lexicon 0.12.14", -] - [[package]] name = "pyo3-build-config" version = "0.24.2" @@ -804,24 +755,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99636d423fa2ca130fa5acde3059308006d46f98caac629418e53f7ebb1e9999" dependencies = [ "once_cell", - "target-lexicon 0.13.2", + "target-lexicon", ] [[package]] name = "pyo3-ffi" -version = "0.21.2" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01be5843dc60b916ab4dad1dca6d20b9b4e6ddc8e15f50c47fe6d85f1fb97403" +checksum = "78f9cf92ba9c409279bc3305b5409d90db2d2c22392d443a87df3a1adad59e33" dependencies = [ "libc", - "pyo3-build-config 0.21.2", + "pyo3-build-config", ] [[package]] name = "pyo3-macros" -version = "0.21.2" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77b34069fc0682e11b31dbd10321cbf94808394c56fd996796ce45217dfac53c" +checksum = "0b999cb1a6ce21f9a6b147dcf1be9ffedf02e0043aec74dc390f3007047cecd9" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -831,22 +782,22 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.21.2" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08260721f32db5e1a5beae69a55553f56b99bd0e1c3e6e0a5e8851a9d0f5a85c" +checksum = "822ece1c7e1012745607d5cf0bcb2874769f0f7cb34c4cde03b9358eb9ef911a" dependencies = [ "heck", "proc-macro2", - "pyo3-build-config 0.21.2", + "pyo3-build-config", "quote", "syn", ] [[package]] name = "pythonize" -version = "0.21.1" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0664248812c38cc55a4ed07f88e4df516ce82604b93b1ffdc041aa77a6cb3c" +checksum = "d5bcac0d0b71821f0d69e42654f1e15e5c94b85196446c4de9588951a2117e7b" dependencies = [ "pyo3", "serde", @@ -927,15 +878,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "regex" version = "1.10.2" @@ -987,7 +929,7 @@ version = "0.38.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" dependencies = [ - "bitflags 2.4.1", + "bitflags", "errno", "libc", "linux-raw-sys 0.4.10", @@ -1000,7 +942,7 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" dependencies = [ - "bitflags 2.4.1", + "bitflags", "errno", "libc", "linux-raw-sys 0.9.4", @@ -1113,7 +1055,7 @@ dependencies = [ "futures", "itertools", "pyo3", - "pyo3-build-config 0.24.2", + "pyo3-build-config", "pythonize", "serde", "serde_json", @@ -1266,12 +1208,6 @@ dependencies = [ "serde", ] -[[package]] -name = "target-lexicon" -version = "0.12.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" - [[package]] name = "target-lexicon" version = "0.13.2" @@ -1627,7 +1563,7 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags 2.4.1", + "bitflags", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 34db8db6..101c4927 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,10 +19,10 @@ chrono = "0.4.40" tantivy = "0.24.0" itertools = "0.14.0" futures = "0.3.31" -pythonize = "0.21.0" +pythonize = "0.24.0" serde = "1.0" serde_json = "1.0.140" [dependencies.pyo3] -version = "0.21.0" +version = "0.24.2" features = ["chrono", "extension-module"] diff --git a/src/document.rs b/src/document.rs index afd655eb..10d18a1f 100644 --- a/src/document.rs +++ b/src/document.rs @@ -52,9 +52,8 @@ pub(crate) fn extract_value(any: &Bound) -> PyResult { return Ok(Value::Bytes(b)); } if let Ok(dict) = any.downcast::() { - if let Ok(json_dict) = pythonize::depythonize_bound::< - BTreeMap, - >(dict.clone().into_any()) + if let Ok(json_dict) = + pythonize::depythonize::>(&dict.as_ref()) { return Ok(Value::Object(json_dict.into_iter().collect())); } else { @@ -136,8 +135,8 @@ pub(crate) fn extract_value_for_type( let dict = any .downcast::() .map_err(to_pyerr_for_type("Json", field_name, any))?; - let map = pythonize::depythonize_bound::>( - dict.clone().into_any(), + let map = pythonize::depythonize::>( + &dict.as_ref(), )?; Value::Object(map.into_iter().collect()) } @@ -312,6 +311,60 @@ where i64::deserialize(deserializer).map(tv::DateTime::from_timestamp_nanos) } +fn deserialize_json_object_as_i64<'de, D>( + deserializer: D, +) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + let raw_object = Vec::deserialize(deserializer)?; + let converted_object = raw_object + .into_iter() + .map(|(key, value)| { + let converted_value = match value { + serde_json::Value::Number(num) => { + if let Some(i) = num.as_i64() { + Value::I64(i) + } else { + Value::F64(num.as_f64().unwrap()) + } + } + serde_json::Value::Object(obj) => { + Value::Object(deserialize_json_object_as_i64_inner(obj)) + } + _ => Value::from(value), + }; + (key, converted_value) + }) + .collect(); + + Ok(converted_object) +} + +fn deserialize_json_object_as_i64_inner( + raw_object: serde_json::Map, +) -> Vec<(String, Value)> { + raw_object + .into_iter() + .map(|(key, value)| { + let converted_value = match value { + serde_json::Value::Number(num) => { + if let Some(i) = num.as_i64() { + Value::I64(i) + } else { + Value::F64(num.as_f64().unwrap()) + } + } + serde_json::Value::Object(obj) => { + Value::Object(deserialize_json_object_as_i64_inner(obj)) + } + _ => Value::from(value), + }; + (key, converted_value) + }) + .collect() +} + /// An equivalent type to [`tantivy::schema::Value`], but unlike the tantivy crate's serialization /// implementation, it uses tagging in its serialization and deserialization to differentiate /// between different integer types. @@ -347,6 +400,7 @@ enum SerdeValue { /// Array Array(Vec), /// Object value. + #[serde(deserialize_with = "deserialize_json_object_as_i64")] Object(Vec<(String, Value)>), /// IpV6 Address. Internally there is no IpV4, it needs to be converted to `Ipv6Addr`. IpAddr(Ipv6Addr), @@ -581,6 +635,7 @@ impl Document { } #[staticmethod] + #[pyo3(signature = (py_dict, schema=None))] fn from_dict( py_dict: &Bound, schema: Option<&Schema>, @@ -719,9 +774,7 @@ impl Document { serde_json::from_str(json_str).map_err(to_pyerr)?; self.add_value(field_name, json_map); Ok(()) - } else if let Ok(json_map) = - pythonize::depythonize_bound::(value.clone()) - { + } else if let Ok(json_map) = pythonize::depythonize::(value) { self.add_value(field_name, json_map); Ok(()) } else { @@ -826,7 +879,7 @@ impl Document { #[staticmethod] fn _internal_from_pythonized(serialized: &Bound) -> PyResult { - pythonize::depythonize_bound(serialized.clone()).map_err(to_pyerr) + pythonize::depythonize(&serialized).map_err(to_pyerr) } fn __reduce__<'a>( diff --git a/src/query.rs b/src/query.rs index 110f75b7..20c55740 100644 --- a/src/query.rs +++ b/src/query.rs @@ -15,10 +15,8 @@ use tantivy as tv; struct OccurQueryPair(Occur, Query); impl<'source> FromPyObject<'source> for OccurQueryPair { - fn extract(ob: &'source PyAny) -> PyResult { - let tuple = ob.downcast::()?; - let occur = tuple.get_item(0)?.extract()?; - let query = tuple.get_item(1)?.extract()?; + fn extract_bound(ob: &Bound<'source, PyAny>) -> PyResult { + let (occur, query): (Occur, Query) = ob.extract()?; Ok(OccurQueryPair(occur, query)) } @@ -223,6 +221,7 @@ impl Query { /// Construct a Tantivy's DisjunctionMaxQuery #[staticmethod] + #[pyo3(signature = (subqueries, tie_breaker=None))] pub(crate) fn disjunction_max_query( subqueries: Vec, tie_breaker: Option>, diff --git a/src/schema.rs b/src/schema.rs index f18f84e3..4d7bb997 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -63,7 +63,7 @@ impl Schema { #[staticmethod] fn _internal_from_pythonized(serialized: &Bound) -> PyResult { - pythonize::depythonize_bound(serialized.clone()).map_err(to_pyerr) + pythonize::depythonize(&serialized).map_err(to_pyerr) } fn __reduce__<'a>(