Skip to content

Commit 6d0c119

Browse files
committed
Add payload deserialization support
1 parent a9267ee commit 6d0c119

File tree

6 files changed

+861
-5
lines changed

6 files changed

+861
-5
lines changed

src/error.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ impl Debug for NotA<bool> {
6060

6161
impl Display for NotA<bool> {
6262
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
63-
f.write_str(concat!("not a bool"))
63+
f.write_str("not a bool")
6464
}
6565
}
6666

@@ -87,7 +87,7 @@ impl Debug for NotA<i64> {
8787

8888
impl Display for NotA<i64> {
8989
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
90-
f.write_str(concat!("not an i64"))
90+
f.write_str("not an i64")
9191
}
9292
}
9393

@@ -114,7 +114,7 @@ impl Debug for NotA<f64> {
114114

115115
impl Display for NotA<f64> {
116116
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
117-
f.write_str(concat!("not a f64"))
117+
f.write_str("not a f64")
118118
}
119119
}
120120

@@ -141,7 +141,7 @@ impl Debug for NotA<String> {
141141

142142
impl Display for NotA<String> {
143143
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
144-
f.write_str(concat!("not a String"))
144+
f.write_str("not a String")
145145
}
146146
}
147147

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ pub mod prelude;
165165
#[doc(hidden)]
166166
pub mod serde;
167167

168+
#[cfg(feature = "serde")]
169+
pub mod serde_deser;
170+
168171
// Re-exports
169172
pub use crate::payload::Payload;
170173
pub use crate::qdrant_client::error::QdrantError;

src/payload.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
use std::collections::HashMap;
22

3+
#[cfg(feature = "serde")]
4+
use serde::de::IntoDeserializer;
35
#[cfg(feature = "serde")]
46
use serde::{Deserialize, Serialize};
57

68
use crate::qdrant::{GeoPoint, Struct, Value};
9+
#[cfg(feature = "serde")]
10+
use crate::QdrantError;
711

812
/// Point payload
913
///
@@ -69,6 +73,15 @@ impl Payload {
6973
pub fn insert(&mut self, key: impl ToString, val: impl Into<Value>) {
7074
self.0.insert(key.to_string(), val.into());
7175
}
76+
77+
/// Deserializes the payload directly into `T`. This requires T to implement `serde::Deserialize`.
78+
/// Returns an error if `T` and the payload have a different structure.
79+
#[cfg(feature = "serde")]
80+
pub fn deserialize<T: serde::de::DeserializeOwned>(self) -> Result<T, QdrantError> {
81+
Ok(T::deserialize(
82+
Struct { fields: self.0 }.into_deserializer(),
83+
)?)
84+
}
7285
}
7386

7487
impl From<HashMap<String, Value>> for Payload {

src/qdrant_client/error.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use thiserror::Error;
22
use tonic::codegen::http::uri::InvalidUri;
33

4+
#[cfg(feature = "serde")]
5+
use crate::serde_deser::DeserPayloadError;
6+
47
/// Qdrant client error
58
#[derive(Error, Debug)]
69
pub enum QdrantError {
@@ -47,6 +50,24 @@ pub enum QdrantError {
4750
#[cfg(feature = "serde")]
4851
#[error("JSON cannot be converted to payload, only JSON objects are supported")]
4952
JsonToPayload(serde_json::Value),
53+
54+
/// Error when failing to deserializing payload using `payload.deserialize()`.
55+
#[cfg(feature = "serde")]
56+
#[error("Error in payload deserialization")]
57+
PayloadDeserialization(#[from] DeserPayloadError),
58+
}
59+
60+
impl QdrantError {
61+
// Only used in tests for now.
62+
#[cfg(feature = "serde")]
63+
#[allow(dead_code)]
64+
pub(crate) fn as_payload_deserialization(&self) -> Option<&DeserPayloadError> {
65+
if let QdrantError::PayloadDeserialization(err) = self {
66+
Some(err)
67+
} else {
68+
None
69+
}
70+
}
5071
}
5172

5273
impl From<tonic::Status> for QdrantError {

0 commit comments

Comments
 (0)