mirror of
https://github.com/meilisearch/meilisearch.git
synced 2024-11-26 03:55:07 +08:00
WIP jayson integration
This commit is contained in:
parent
4c1f034d9f
commit
ff564f6d05
@ -1,7 +1,7 @@
|
|||||||
use actix_web::{dev::Payload, web::Json, FromRequest, HttpRequest};
|
use actix_web::{dev::Payload, web::Json, FromRequest, HttpRequest};
|
||||||
use futures::ready;
|
use futures::ready;
|
||||||
use jayson::{DeserializeError, DeserializeFromValue};
|
use jayson::{DeserializeError, DeserializeFromValue};
|
||||||
use meilisearch_types::error::{Code, ErrorCode, ResponseError};
|
use meilisearch_types::error::{ErrorCode, ResponseError};
|
||||||
use std::{
|
use std::{
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
future::Future,
|
future::Future,
|
||||||
@ -34,7 +34,7 @@ where
|
|||||||
E: DeserializeError + ErrorCode + 'static,
|
E: DeserializeError + ErrorCode + 'static,
|
||||||
T: DeserializeFromValue<E>,
|
T: DeserializeFromValue<E>,
|
||||||
{
|
{
|
||||||
type Error = ResponseError;
|
type Error = actix_web::Error;
|
||||||
type Future = ValidatedJsonExtractFut<T, E>;
|
type Future = ValidatedJsonExtractFut<T, E>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -56,7 +56,7 @@ where
|
|||||||
T: DeserializeFromValue<E>,
|
T: DeserializeFromValue<E>,
|
||||||
E: DeserializeError + ErrorCode + 'static,
|
E: DeserializeError + ErrorCode + 'static,
|
||||||
{
|
{
|
||||||
type Output = Result<ValidatedJson<T, E>, ResponseError>;
|
type Output = Result<ValidatedJson<T, E>, actix_web::Error>;
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let this = self.get_mut();
|
let this = self.get_mut();
|
||||||
@ -64,13 +64,10 @@ where
|
|||||||
let res = ready!(Pin::new(&mut this.fut).poll(cx));
|
let res = ready!(Pin::new(&mut this.fut).poll(cx));
|
||||||
|
|
||||||
let res = match res {
|
let res = match res {
|
||||||
Err(err) => Err(ResponseError::from_msg(
|
Err(err) => Err(err),
|
||||||
format!("{err}"),
|
|
||||||
Code::MalformedPayload,
|
|
||||||
)),
|
|
||||||
Ok(data) => match jayson::deserialize::<_, _, E>(data.into_inner()) {
|
Ok(data) => match jayson::deserialize::<_, _, E>(data.into_inner()) {
|
||||||
Ok(data) => Ok(ValidatedJson::new(data)),
|
Ok(data) => Ok(ValidatedJson::new(data)),
|
||||||
Err(e) => Err(e.into()),
|
Err(e) => Err(ResponseError::from(e).into()),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
use log::debug;
|
use log::debug;
|
||||||
|
|
||||||
|
use crate::analytics::Analytics;
|
||||||
|
use crate::extractors::authentication::{policies::*, GuardedData};
|
||||||
|
use crate::extractors::jayson::ValidatedJson;
|
||||||
|
use crate::task::SummarizedTaskView;
|
||||||
use actix_web::{web, HttpRequest, HttpResponse};
|
use actix_web::{web, HttpRequest, HttpResponse};
|
||||||
use meilisearch_lib::index::Settings;
|
use meilisearch_lib::index::Settings;
|
||||||
use meilisearch_lib::index_controller::Update;
|
use meilisearch_lib::index_controller::Update;
|
||||||
@ -7,11 +11,6 @@ use meilisearch_lib::MeiliSearch;
|
|||||||
use meilisearch_types::error::{MeiliDeserError, ResponseError};
|
use meilisearch_types::error::{MeiliDeserError, ResponseError};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::analytics::Analytics;
|
|
||||||
use crate::extractors::authentication::{policies::*, GuardedData};
|
|
||||||
use crate::extractors::jayson::ValidatedJson;
|
|
||||||
use crate::task::SummarizedTaskView;
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! make_setting_route {
|
macro_rules! make_setting_route {
|
||||||
($route:literal, $update_verb:ident, $type:ty, $attr:ident, $camelcase_attr:literal, $analytics_var:ident, $analytics:expr) => {
|
($route:literal, $update_verb:ident, $type:ty, $attr:ident, $camelcase_attr:literal, $analytics_var:ident, $analytics:expr) => {
|
||||||
@ -55,7 +54,10 @@ macro_rules! make_setting_route {
|
|||||||
pub async fn update(
|
pub async fn update(
|
||||||
meilisearch: GuardedData<ActionPolicy<{ actions::SETTINGS_UPDATE }>, MeiliSearch>,
|
meilisearch: GuardedData<ActionPolicy<{ actions::SETTINGS_UPDATE }>, MeiliSearch>,
|
||||||
index_uid: actix_web::web::Path<String>,
|
index_uid: actix_web::web::Path<String>,
|
||||||
body: actix_web::web::Json<Option<$type>>,
|
body: crate::extractors::jayson::ValidatedJson<
|
||||||
|
Option<$type>,
|
||||||
|
meilisearch_types::error::MeiliDeserError,
|
||||||
|
>,
|
||||||
req: HttpRequest,
|
req: HttpRequest,
|
||||||
$analytics_var: web::Data<dyn Analytics>,
|
$analytics_var: web::Data<dyn Analytics>,
|
||||||
) -> std::result::Result<HttpResponse, ResponseError> {
|
) -> std::result::Result<HttpResponse, ResponseError> {
|
||||||
|
@ -36,7 +36,7 @@ pub mod test {
|
|||||||
use super::error::Result;
|
use super::error::Result;
|
||||||
use super::index::Index;
|
use super::index::Index;
|
||||||
use super::Document;
|
use super::Document;
|
||||||
use super::{Checked, IndexMeta, IndexStats, SearchQuery, SearchResult, Settings};
|
use super::{IndexMeta, IndexStats, SearchQuery, SearchResult, Settings};
|
||||||
use crate::update_file_store::UpdateFileStore;
|
use crate::update_file_store::UpdateFileStore;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -67,6 +67,7 @@ pub struct TypoSettings {
|
|||||||
|
|
||||||
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, DeserializeFromValue)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, DeserializeFromValue)]
|
||||||
|
#[jayson(rename_all = camelCase, deny_unknown_fields)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct FacetingSettings {
|
pub struct FacetingSettings {
|
||||||
@ -79,6 +80,7 @@ pub struct FacetingSettings {
|
|||||||
#[derive(
|
#[derive(
|
||||||
Debug, Clone, Default, Serialize, Deserialize, PartialEq, jayson::DeserializeFromValue,
|
Debug, Clone, Default, Serialize, Deserialize, PartialEq, jayson::DeserializeFromValue,
|
||||||
)]
|
)]
|
||||||
|
#[jayson(rename_all = camelCase, deny_unknown_fields)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct PaginationSettings {
|
pub struct PaginationSettings {
|
||||||
@ -92,10 +94,10 @@ pub struct PaginationSettings {
|
|||||||
#[derive(
|
#[derive(
|
||||||
Debug, Clone, Default, Serialize, Deserialize, PartialEq, jayson::DeserializeFromValue,
|
Debug, Clone, Default, Serialize, Deserialize, PartialEq, jayson::DeserializeFromValue,
|
||||||
)]
|
)]
|
||||||
|
#[jayson(rename_all = camelCase, deny_unknown_fields)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
||||||
#[jayson(rename_all = camelCase, deny_unknown_fields)]
|
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
#[serde(
|
#[serde(
|
||||||
default,
|
default,
|
||||||
@ -122,7 +124,7 @@ pub struct Settings {
|
|||||||
#[cfg_attr(test, proptest(strategy = "test::setting_strategy()"))]
|
#[cfg_attr(test, proptest(strategy = "test::setting_strategy()"))]
|
||||||
pub sortable_attributes: Setting<BTreeSet<String>>,
|
pub sortable_attributes: Setting<BTreeSet<String>>,
|
||||||
#[serde(default, skip_serializing_if = "Setting::is_not_set")]
|
#[serde(default, skip_serializing_if = "Setting::is_not_set")]
|
||||||
#[cfg_attr(test, proptest(strategy = "test::setting_strategy()"))]
|
#[cfg_attr(test, proptest(strategy = "test::criteria_setting_strategy()"))]
|
||||||
#[jayson(needs_predicate)]
|
#[jayson(needs_predicate)]
|
||||||
pub ranking_rules: Setting<Vec<Criterion>>,
|
pub ranking_rules: Setting<Vec<Criterion>>,
|
||||||
#[serde(default, skip_serializing_if = "Setting::is_not_set")]
|
#[serde(default, skip_serializing_if = "Setting::is_not_set")]
|
||||||
@ -162,9 +164,7 @@ impl Settings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn map_searchable_or_displayed_attributes(
|
fn map_searchable_or_displayed_attributes(setting: Setting<Vec<String>>) -> Setting<Vec<String>> {
|
||||||
setting: Setting<Vec<String>>,
|
|
||||||
) -> Setting<Vec<String>> {
|
|
||||||
match setting {
|
match setting {
|
||||||
Setting::Set(fields) => {
|
Setting::Set(fields) => {
|
||||||
if fields.iter().any(|f| f == "*") {
|
if fields.iter().any(|f| f == "*") {
|
||||||
@ -422,10 +422,33 @@ pub fn apply_settings_to_builder(settings: &Settings, builder: &mut milli::updat
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) mod test {
|
pub(crate) mod test {
|
||||||
|
use super::*;
|
||||||
|
use milli::Criterion;
|
||||||
use proptest::prelude::*;
|
use proptest::prelude::*;
|
||||||
|
|
||||||
use super::*;
|
fn criteria_strategy() -> impl Strategy<Value = Vec<Criterion>> {
|
||||||
|
proptest::collection::vec(
|
||||||
|
prop_oneof![
|
||||||
|
Just(Criterion::Words),
|
||||||
|
Just(Criterion::Typo),
|
||||||
|
Just(Criterion::Proximity),
|
||||||
|
Just(Criterion::Attribute),
|
||||||
|
Just(Criterion::Sort),
|
||||||
|
Just(Criterion::Exactness),
|
||||||
|
any::<String>().prop_map(Criterion::Asc),
|
||||||
|
any::<String>().prop_map(Criterion::Desc),
|
||||||
|
],
|
||||||
|
0..100,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn criteria_setting_strategy() -> impl Strategy<Value = Setting<Vec<Criterion>>> {
|
||||||
|
prop_oneof![
|
||||||
|
Just(Setting::NotSet),
|
||||||
|
Just(Setting::Reset),
|
||||||
|
criteria_strategy().prop_map(Setting::Set),
|
||||||
|
]
|
||||||
|
}
|
||||||
pub(super) fn setting_strategy<T: Arbitrary + Clone>() -> impl Strategy<Value = Setting<T>> {
|
pub(super) fn setting_strategy<T: Arbitrary + Clone>() -> impl Strategy<Value = Setting<T>> {
|
||||||
prop_oneof![
|
prop_oneof![
|
||||||
Just(Setting::NotSet),
|
Just(Setting::NotSet),
|
||||||
@ -451,11 +474,10 @@ pub(crate) mod test {
|
|||||||
pagination: Setting::NotSet,
|
pagination: Setting::NotSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
let checked = settings.clone().check();
|
assert_eq!(settings.displayed_attributes, settings.displayed_attributes);
|
||||||
assert_eq!(settings.displayed_attributes, checked.displayed_attributes);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
settings.searchable_attributes,
|
settings.searchable_attributes,
|
||||||
checked.searchable_attributes
|
settings.searchable_attributes
|
||||||
);
|
);
|
||||||
|
|
||||||
// test wildcard
|
// test wildcard
|
||||||
@ -474,8 +496,7 @@ pub(crate) mod test {
|
|||||||
pagination: Setting::NotSet,
|
pagination: Setting::NotSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
let checked = settings.check();
|
assert_eq!(settings.displayed_attributes, Setting::Reset);
|
||||||
assert_eq!(checked.displayed_attributes, Setting::Reset);
|
assert_eq!(settings.searchable_attributes, Setting::Reset);
|
||||||
assert_eq!(checked.searchable_attributes, Setting::Reset);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user