Skip to content

Commit

Permalink
Deprecate the serde module (#138)
Browse files Browse the repository at this point in the history
* Deprecate serde module

* Rename errors to error

* Add more payload conversion functions

* Update documentation

* Allow deprecated usage in serde tests

* Move serde tests, fix deprecation warning
  • Loading branch information
timvisee committed Jun 26, 2024
1 parent f2eaa01 commit 57db89d
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 89 deletions.
12 changes: 6 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,8 @@
pub mod auth;
pub mod builder_types;
pub mod payload;
#[cfg(feature = "serde")]
pub mod serde;

// Qdrant API types
// Generated Qdrant API types
/// API types
#[allow(clippy::all)]
#[rustfmt::skip]
Expand Down Expand Up @@ -131,11 +129,13 @@ pub mod error;
/// Deprecated prelude
#[deprecated(since = "1.10.0", note = "use types directly")]
pub mod prelude;
/// Deprecated serde helper
#[cfg(feature = "serde")]
#[deprecated(since = "1.10.0", note = "use `Payload::from_json_object` instead")]
pub mod serde;

// Re-exports
pub use crate::qdrant_client::{
config::QdrantConfig, errors::Error, Qdrant, QdrantBuilder, Result,
};
pub use crate::qdrant_client::{config::QdrantConfig, error::Error, Qdrant, QdrantBuilder, Result};

// Vendored re-exports
#[doc(no_inline)]
Expand Down
101 changes: 101 additions & 0 deletions src/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ use std::collections::HashMap;
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Payload(pub(crate) HashMap<String, Value>);

#[cfg(feature = "serde")]
impl Payload {
/// Convert a JSON object into a Payload
///
/// Returns `None` if the given JSON value is not an object.
#[inline]
pub fn from_json_object(value: serde_json::Value) -> Option<Self> {
if let serde_json::Value::Object(object) = value {
Some(object.into())
} else {
None
}
}
}

impl From<Payload> for HashMap<String, Value> {
#[inline]
fn from(payload: Payload) -> Self {
Expand All @@ -26,6 +41,14 @@ impl From<HashMap<&str, Value>> for Payload {
}
}

#[cfg(feature = "serde")]
impl From<serde_json::Map<String, serde_json::Value>> for Payload {
#[inline]
fn from(obj: serde_json::Map<String, serde_json::Value>) -> Self {
Payload::new_from_hashmap(obj.into_iter().map(|(k, v)| (k, v.into())).collect())
}
}

impl<K, const N: usize> From<[(K, Value); N]> for Payload
where
K: Into<String>,
Expand All @@ -52,3 +75,81 @@ impl Payload {
self.0.insert(key.to_string(), val.into());
}
}

#[cfg(feature = "serde")]
#[cfg(test)]
mod tests {
use super::*;
use crate::client::Payload;
use serde_json::json;

#[test]
fn json_payload_round_trip() {
let payload: Payload = vec![
("some_string", "Bar".into()),
("some_bool", true.into()),
("some_int", 12.into()),
("some_float", 2.3.into()),
("some_seq", vec!["elem1", "elem2"].into()),
("some_obj", vec![("key", "value")].into()),
]
.into_iter()
.collect::<HashMap<_, Value>>()
.into();

// payload -> Json string
let json_value = serde_json::to_string(&payload).unwrap();

// Json string -> payload
let payload_back: Payload = serde_json::from_str(&json_value).unwrap();

// assert round trip
assert_eq!(payload, payload_back);
}

#[test]
fn payload_from_string() {
let json = r#"{
"some_string": "Bar",
"some_bool": true,
"some_int": 12,
"some_float": 2.3,
"some_seq": ["elem1", "elem2"],
"some_obj": {"key": "value"}
}"#;

// String -> payload
let parsed_payload: Payload = serde_json::from_str(json).unwrap();

let expected: Payload = vec![
("some_string", "Bar".into()),
("some_bool", true.into()),
("some_int", 12.into()),
("some_float", 2.3.into()),
("some_seq", vec!["elem1", "elem2"].into()),
("some_obj", vec![("key", "value")].into()),
]
.into_iter()
.collect::<HashMap<_, Value>>()
.into();

// assert expected
assert_eq!(parsed_payload, expected);
}

#[test]
fn test_json_macro() {
let json_value = json!({
"some_string": "Bar",
"some_bool": true,
"some_int": 12,
"some_float": 2.3,
"some_seq": ["elem1", "elem2"],
"some_obj": {"key": "value"}
});

let payload: Payload = Payload::from_json_object(json_value).unwrap();

eprintln!("payload = {:#?}", payload);
}
}
File renamed without changes.
2 changes: 1 addition & 1 deletion src/qdrant_client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ mod builers;
mod collection;
pub mod config;
mod conversions;
pub mod errors;
pub mod error;
mod points;
mod query;
mod sharding_keys;
Expand Down
2 changes: 1 addition & 1 deletion src/qdrant_client/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl Qdrant {
&self,
options: impl Into<crate::qdrant::SnapshotDownload>,
) -> Result<()> {
use crate::qdrant_client::errors::Error;
use crate::qdrant_client::error::Error;
use futures_util::StreamExt;
use std::io::Write;

Expand Down
85 changes: 4 additions & 81 deletions src/serde.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![allow(deprecated)]

use crate::client::Payload;
use crate::qdrant::value::Kind;
use crate::qdrant::{ListValue, Struct, Value};
Expand Down Expand Up @@ -100,10 +102,8 @@ impl TryFrom<serde_json::Value> for Payload {
type Error = PayloadConversionError;

fn try_from(value: serde_json::Value) -> Result<Self, Self::Error> {
if let serde_json::Value::Object(obj) = value {
Ok(Payload::new_from_hashmap(
obj.into_iter().map(|(k, v)| (k, v.into())).collect(),
))
if let serde_json::Value::Object(object) = value {
Ok(object.into())
} else {
Err(PayloadConversionError(value))
}
Expand All @@ -120,80 +120,3 @@ impl<'de> Deserialize<'de> for Value {
Ok(serde_value.into())
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::client::Payload;
use serde_json::json;

#[test]
fn json_payload_round_trip() {
let payload: Payload = vec![
("some_string", "Bar".into()),
("some_bool", true.into()),
("some_int", 12.into()),
("some_float", 2.3.into()),
("some_seq", vec!["elem1", "elem2"].into()),
("some_obj", vec![("key", "value")].into()),
]
.into_iter()
.collect::<HashMap<_, Value>>()
.into();

// payload -> Json string
let json_value = serde_json::to_string(&payload).unwrap();

// Json string -> payload
let payload_back: Payload = serde_json::from_str(&json_value).unwrap();

// assert round trip
assert_eq!(payload, payload_back);
}

#[test]
fn payload_from_string() {
let json = r#"{
"some_string": "Bar",
"some_bool": true,
"some_int": 12,
"some_float": 2.3,
"some_seq": ["elem1", "elem2"],
"some_obj": {"key": "value"}
}"#;

// String -> payload
let parsed_payload: Payload = serde_json::from_str(json).unwrap();

let expected: Payload = vec![
("some_string", "Bar".into()),
("some_bool", true.into()),
("some_int", 12.into()),
("some_float", 2.3.into()),
("some_seq", vec!["elem1", "elem2"].into()),
("some_obj", vec![("key", "value")].into()),
]
.into_iter()
.collect::<HashMap<_, Value>>()
.into();

// assert expected
assert_eq!(parsed_payload, expected);
}

#[test]
fn test_json_macro() {
let json_value = json!({
"some_string": "Bar",
"some_bool": true,
"some_int": 12,
"some_float": 2.3,
"some_seq": ["elem1", "elem2"],
"some_obj": {"key": "value"}
});

let payload: Payload = json_value.try_into().unwrap();

eprintln!("payload = {:#?}", payload);
}
}

0 comments on commit 57db89d

Please sign in to comment.