use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "lowercase")]
pub enum QueryType {
Simple,
Full,
Semantic,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "lowercase")]
pub enum SearchMode {
Any,
All,
}
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
#[serde(rename_all = "camelCase")]
pub struct SearchRequest {
pub count: bool,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(serialize_with = "serialize_option_vec_as_string")]
pub select: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub search: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(serialize_with = "serialize_option_vec_as_string")]
pub search_fields: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub search_mode: Option<SearchMode>,
#[serde(skip_serializing_if = "Option::is_none")]
pub filter: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub facets: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub vector_queries: Option<Vec<VectorKind>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub semantic_configuration: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub query_type: Option<QueryType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub orderby: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub minimum_coverage: Option<u8>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(serialize_with = "serialize_option_vec_as_string")]
pub highlight: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub highlight_post_tag: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub highlight_pre_tag: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub session_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub top: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
pub skip: Option<u16>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(untagged)]
pub enum VectorKind {
VectorQuery {
kind: String,
vector: Vec<f32>,
k: u16,
#[serde(serialize_with = "serialize_vec_as_string")]
fields: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
weight: Option<f32>,
},
TextQuery {
kind: String,
text: String,
k: u16,
#[serde(serialize_with = "serialize_vec_as_string")]
fields: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
weight: Option<f32>,
},
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct SearchResult<T> {
#[serde(rename = "@search.score")]
pub score: f64,
#[serde(rename = "@search.highlights", skip_serializing_if = "Option::is_none")]
pub highlights: Option<serde_json::Value>,
#[serde(flatten)]
pub document: T,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct SearchResponse<T> {
pub value: Vec<SearchResult<T>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub facets: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub answers: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub count: Option<u64>,
}
fn serialize_vec_as_string<S>(vec: &[String], serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let joined = vec.join(",");
serializer.serialize_str(&joined)
}
fn serialize_option_vec_as_string<S>(
vec: &Option<Vec<String>>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let joined = vec.as_ref().unwrap_or(&vec![]).join(",");
serializer.serialize_str(&joined)
}