use super::{Error, QuerySchema, ValidationError, FORM_ENCODED_MIME_TYPE};
use crate::blobs::Blob;
#[cfg(feature = "fp-bindgen")]
use fp_bindgen::prelude::Serializable;
use serde::{Deserialize, Serialize};
use typed_builder::TypedBuilder;
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::providers")
)]
#[non_exhaustive]
pub struct AutoSuggestRequest {
pub query: String,
pub query_type: String,
pub field: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub other_field_data: Option<String>,
}
impl AutoSuggestRequest {
pub fn parse(query_data: Blob) -> Result<Self, Error> {
if query_data.mime_type != FORM_ENCODED_MIME_TYPE {
return Err(Error::UnsupportedRequest);
}
let mut query = String::new();
let mut query_type = String::new();
let mut field = String::new();
let mut other_field_data = None;
for (key, value) in form_urlencoded::parse(&query_data.data) {
match key.as_ref() {
"query" => query = value.to_string(),
"query_type" => query_type = value.to_string(),
"field" => field = value.to_string(),
"other_field_data" => other_field_data = Some(value.to_string()),
_ => {}
}
}
let mut errors = Vec::new();
if field.is_empty() {
errors.push(
ValidationError::builder()
.field_name("field".to_owned())
.message("Missing field".to_owned())
.build(),
);
}
if query_type.is_empty() {
errors.push(
ValidationError::builder()
.field_name("query_type".to_owned())
.message("Missing query_type".to_owned())
.build(),
);
}
match errors.is_empty() {
true => Ok(Self {
query,
query_type,
field,
other_field_data,
}),
false => Err(Error::ValidationError { errors }),
}
}
pub fn schema() -> QuerySchema {
QuerySchema::default()
}
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize, TypedBuilder)]
#[cfg_attr(
feature = "fp-bindgen",
derive(Serializable),
fp(rust_module = "fiberplane_models::providers")
)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct Suggestion {
#[serde(skip_serializing_if = "Option::is_none")]
pub from: Option<u32>,
pub text: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}