mirror of
https://github.com/meilisearch/meilisearch.git
synced 2024-11-26 03:55:07 +08:00
Start jayson integration
This commit is contained in:
parent
9082679609
commit
ba82584328
80
Cargo.lock
generated
80
Cargo.lock
generated
@ -1127,6 +1127,14 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "filter-parser"
|
||||||
|
version = "0.29.3"
|
||||||
|
dependencies = [
|
||||||
|
"nom",
|
||||||
|
"nom_locate",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filter-parser"
|
name = "filter-parser"
|
||||||
version = "0.29.3"
|
version = "0.29.3"
|
||||||
@ -1152,6 +1160,13 @@ dependencies = [
|
|||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flatten-serde-json"
|
||||||
|
version = "0.29.3"
|
||||||
|
dependencies = [
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flatten-serde-json"
|
name = "flatten-serde-json"
|
||||||
version = "0.29.3"
|
version = "0.29.3"
|
||||||
@ -1683,6 +1698,13 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "json-depth-checker"
|
||||||
|
version = "0.29.3"
|
||||||
|
dependencies = [
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "json-depth-checker"
|
name = "json-depth-checker"
|
||||||
version = "0.29.3"
|
version = "0.29.3"
|
||||||
@ -2031,7 +2053,7 @@ dependencies = [
|
|||||||
"enum-iterator",
|
"enum-iterator",
|
||||||
"hmac",
|
"hmac",
|
||||||
"meilisearch-types",
|
"meilisearch-types",
|
||||||
"milli",
|
"milli 0.29.3 (git+https://github.com/meilisearch/milli.git?tag=v0.29.3)",
|
||||||
"rand",
|
"rand",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@ -2140,11 +2162,12 @@ dependencies = [
|
|||||||
"http",
|
"http",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"itertools",
|
"itertools",
|
||||||
|
"jayson",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"meilisearch-auth",
|
"meilisearch-auth",
|
||||||
"meilisearch-types",
|
"meilisearch-types",
|
||||||
"milli",
|
"milli 0.29.3",
|
||||||
"mime",
|
"mime",
|
||||||
"mockall",
|
"mockall",
|
||||||
"nelson",
|
"nelson",
|
||||||
@ -2182,6 +2205,8 @@ name = "meilisearch-types"
|
|||||||
version = "0.28.0"
|
version = "0.28.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-web",
|
"actix-web",
|
||||||
|
"jayson",
|
||||||
|
"milli 0.29.3",
|
||||||
"proptest",
|
"proptest",
|
||||||
"proptest-derive",
|
"proptest-derive",
|
||||||
"serde",
|
"serde",
|
||||||
@ -2212,6 +2237,51 @@ dependencies = [
|
|||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "milli"
|
||||||
|
version = "0.29.3"
|
||||||
|
dependencies = [
|
||||||
|
"bimap",
|
||||||
|
"bincode",
|
||||||
|
"bstr",
|
||||||
|
"byteorder",
|
||||||
|
"charabia",
|
||||||
|
"concat-arrays",
|
||||||
|
"crossbeam-channel",
|
||||||
|
"csv",
|
||||||
|
"either",
|
||||||
|
"filter-parser 0.29.3",
|
||||||
|
"flatten-serde-json 0.29.3",
|
||||||
|
"fst",
|
||||||
|
"fxhash",
|
||||||
|
"geoutils",
|
||||||
|
"grenad",
|
||||||
|
"heed",
|
||||||
|
"itertools",
|
||||||
|
"jayson",
|
||||||
|
"json-depth-checker 0.29.3",
|
||||||
|
"levenshtein_automata",
|
||||||
|
"log",
|
||||||
|
"logging_timer",
|
||||||
|
"memmap2",
|
||||||
|
"obkv",
|
||||||
|
"once_cell",
|
||||||
|
"ordered-float",
|
||||||
|
"rayon",
|
||||||
|
"roaring",
|
||||||
|
"rstar",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"slice-group-by",
|
||||||
|
"smallstr",
|
||||||
|
"smallvec",
|
||||||
|
"smartstring",
|
||||||
|
"tempfile",
|
||||||
|
"thiserror",
|
||||||
|
"time 0.3.9",
|
||||||
|
"uuid",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "milli"
|
name = "milli"
|
||||||
version = "0.29.3"
|
version = "0.29.3"
|
||||||
@ -2226,15 +2296,15 @@ dependencies = [
|
|||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"csv",
|
"csv",
|
||||||
"either",
|
"either",
|
||||||
"filter-parser",
|
"filter-parser 0.29.3 (git+https://github.com/meilisearch/milli.git?tag=v0.29.3)",
|
||||||
"flatten-serde-json",
|
"flatten-serde-json 0.29.3 (git+https://github.com/meilisearch/milli.git?tag=v0.29.3)",
|
||||||
"fst",
|
"fst",
|
||||||
"fxhash",
|
"fxhash",
|
||||||
"geoutils",
|
"geoutils",
|
||||||
"grenad",
|
"grenad",
|
||||||
"heed",
|
"heed",
|
||||||
"itertools",
|
"itertools",
|
||||||
"json-depth-checker",
|
"json-depth-checker 0.29.3 (git+https://github.com/meilisearch/milli.git?tag=v0.29.3)",
|
||||||
"levenshtein_automata",
|
"levenshtein_automata",
|
||||||
"log",
|
"log",
|
||||||
"logging_timer",
|
"logging_timer",
|
||||||
|
@ -1,6 +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, MergeWithError, ValuePointer};
|
||||||
|
use meilisearch_lib::milli::AscDescError;
|
||||||
use meilisearch_types::error::{Code, ErrorCode, ResponseError};
|
use meilisearch_types::error::{Code, ErrorCode, ResponseError};
|
||||||
use std::{
|
use std::{
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
@ -10,6 +11,66 @@ use std::{
|
|||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// pub struct MeilisearchDeserializeError {
|
||||||
|
// pub Vec<(ValuePointer, Box<dyn Error>)>,
|
||||||
|
// }
|
||||||
|
// impl MergeWithError<AscDescError> for MeilisearchDeserializeError {
|
||||||
|
// fn merge(self_: Option<Self>, other: AscDescError, merge_location: jayson::ValuePointerRef) -> Result<Self, Self> {
|
||||||
|
// todo!()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// /*
|
||||||
|
// {
|
||||||
|
// !
|
||||||
|
// x: {
|
||||||
|
// y: {
|
||||||
|
// z: {
|
||||||
|
// a: 2
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// */
|
||||||
|
// impl MergeWithError<MeilisearchDeserializeError> for MeilisearchDeserializeError {
|
||||||
|
|
||||||
|
// }
|
||||||
|
// impl DeserializeError for MeilisearchDeserializeError{
|
||||||
|
// fn location(&self) -> Option<jayson::ValuePointer> {
|
||||||
|
// todo!()
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn incorrect_value_kind(
|
||||||
|
// self_: Option<Self>,
|
||||||
|
// actual: jayson::ValueKind,
|
||||||
|
// accepted: &[jayson::ValueKind],
|
||||||
|
// location: jayson::ValuePointerRef,
|
||||||
|
// ) -> Result<Self, Self> {
|
||||||
|
// todo!()
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn missing_field(
|
||||||
|
// self_: Option<Self>,
|
||||||
|
// field: &str,
|
||||||
|
// location: jayson::ValuePointerRef,
|
||||||
|
// ) -> Result<Self, Self> {
|
||||||
|
// todo!()
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn unknown_key(
|
||||||
|
// self_: Option<Self>,
|
||||||
|
// key: &str,
|
||||||
|
// accepted: &[&str],
|
||||||
|
// location: jayson::ValuePointerRef,
|
||||||
|
// ) -> Result<Self, Self> {
|
||||||
|
// todo!()
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn unexpected(self_: Option<Self>, msg: &str, location: jayson::ValuePointerRef) -> Result<Self, Self> {
|
||||||
|
// todo!()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
/// Extractor for typed data from Json request payloads
|
/// Extractor for typed data from Json request payloads
|
||||||
/// deserialised by Jayson.
|
/// deserialised by Jayson.
|
||||||
///
|
///
|
||||||
|
@ -4,11 +4,13 @@ use actix_web::{web, HttpRequest, HttpResponse};
|
|||||||
use meilisearch_lib::index::{Settings, Unchecked};
|
use meilisearch_lib::index::{Settings, Unchecked};
|
||||||
use meilisearch_lib::index_controller::Update;
|
use meilisearch_lib::index_controller::Update;
|
||||||
use meilisearch_lib::MeiliSearch;
|
use meilisearch_lib::MeiliSearch;
|
||||||
use meilisearch_types::error::ResponseError;
|
use meilisearch_types::error::{MeiliDeserError, ResponseError};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::analytics::Analytics;
|
use crate::analytics::Analytics;
|
||||||
|
use crate::error::MeilisearchHttpError;
|
||||||
use crate::extractors::authentication::{policies::*, GuardedData};
|
use crate::extractors::authentication::{policies::*, GuardedData};
|
||||||
|
use crate::extractors::jayson::ValidatedJson;
|
||||||
use crate::task::SummarizedTaskView;
|
use crate::task::SummarizedTaskView;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
@ -260,27 +262,27 @@ make_setting_route!(
|
|||||||
"distinctAttribute"
|
"distinctAttribute"
|
||||||
);
|
);
|
||||||
|
|
||||||
make_setting_route!(
|
// make_setting_route!(
|
||||||
"/ranking-rules",
|
// "/ranking-rules",
|
||||||
put,
|
// put,
|
||||||
Vec<String>,
|
// Vec<String>,
|
||||||
ranking_rules,
|
// ranking_rules,
|
||||||
"rankingRules",
|
// "rankingRules",
|
||||||
analytics,
|
// analytics,
|
||||||
|setting: &Option<Vec<String>>, req: &HttpRequest| {
|
// |setting: &Option<Vec<milli::AscDesc>>, req: &HttpRequest| {
|
||||||
use serde_json::json;
|
// use serde_json::json;
|
||||||
|
|
||||||
analytics.publish(
|
// analytics.publish(
|
||||||
"RankingRules Updated".to_string(),
|
// "RankingRules Updated".to_string(),
|
||||||
json!({
|
// json!({
|
||||||
"ranking_rules": {
|
// "ranking_rules": {
|
||||||
"sort_position": setting.as_ref().map(|sort| sort.iter().position(|s| s == "sort")),
|
// "sort_position": setting.as_ref().map(|sort| sort.iter().position(|s| s == "sort")),
|
||||||
}
|
// }
|
||||||
}),
|
// }),
|
||||||
Some(req),
|
// Some(req),
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
);
|
// );
|
||||||
|
|
||||||
make_setting_route!(
|
make_setting_route!(
|
||||||
"/faceting",
|
"/faceting",
|
||||||
@ -348,14 +350,14 @@ generate_configure!(
|
|||||||
distinct_attribute,
|
distinct_attribute,
|
||||||
stop_words,
|
stop_words,
|
||||||
synonyms,
|
synonyms,
|
||||||
ranking_rules,
|
// ranking_rules,
|
||||||
typo_tolerance
|
typo_tolerance
|
||||||
);
|
);
|
||||||
|
|
||||||
pub async fn update_all(
|
pub async fn update_all(
|
||||||
meilisearch: GuardedData<ActionPolicy<{ actions::SETTINGS_UPDATE }>, MeiliSearch>,
|
meilisearch: GuardedData<ActionPolicy<{ actions::SETTINGS_UPDATE }>, MeiliSearch>,
|
||||||
index_uid: web::Path<String>,
|
index_uid: web::Path<String>,
|
||||||
body: web::Json<Settings<Unchecked>>,
|
body: ValidatedJson<Settings<Unchecked>, MeiliDeserError>,
|
||||||
req: HttpRequest,
|
req: HttpRequest,
|
||||||
analytics: web::Data<dyn Analytics>,
|
analytics: web::Data<dyn Analytics>,
|
||||||
) -> Result<HttpResponse, ResponseError> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
@ -365,7 +367,7 @@ pub async fn update_all(
|
|||||||
"Settings Updated".to_string(),
|
"Settings Updated".to_string(),
|
||||||
json!({
|
json!({
|
||||||
"ranking_rules": {
|
"ranking_rules": {
|
||||||
"sort_position": settings.ranking_rules.as_ref().set().map(|sort| sort.iter().position(|s| s == "sort")),
|
"sort_position": settings.ranking_rules.as_ref().set().map(|sort| sort.iter().position(|s| true /*TODO*/)),
|
||||||
},
|
},
|
||||||
"searchable_attributes": {
|
"searchable_attributes": {
|
||||||
"total": settings.searchable_attributes.as_ref().set().map(|searchable| searchable.len()),
|
"total": settings.searchable_attributes.as_ref().set().map(|searchable| searchable.len()),
|
||||||
|
@ -30,7 +30,8 @@ lazy_static = "1.4.0"
|
|||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
meilisearch-auth = { path = "../meilisearch-auth" }
|
meilisearch-auth = { path = "../meilisearch-auth" }
|
||||||
meilisearch-types = { path = "../meilisearch-types" }
|
meilisearch-types = { path = "../meilisearch-types" }
|
||||||
milli = { git = "https://github.com/meilisearch/milli.git", tag = "v0.29.3" }
|
milli = { path = "../../milli/milli" }
|
||||||
|
jayson = { path = "../../jayson" }
|
||||||
mime = "0.3.16"
|
mime = "0.3.16"
|
||||||
num_cpus = "1.13.1"
|
num_cpus = "1.13.1"
|
||||||
obkv = "0.2.0"
|
obkv = "0.2.0"
|
||||||
|
@ -8,7 +8,7 @@ use std::sync::Arc;
|
|||||||
use fst::IntoStreamer;
|
use fst::IntoStreamer;
|
||||||
use milli::heed::{EnvOpenOptions, RoTxn};
|
use milli::heed::{EnvOpenOptions, RoTxn};
|
||||||
use milli::update::{IndexerConfig, Setting};
|
use milli::update::{IndexerConfig, Setting};
|
||||||
use milli::{obkv_to_json, FieldDistribution, DEFAULT_VALUES_PER_FACET};
|
use milli::{obkv_to_json, AscDesc, FieldDistribution, Member, DEFAULT_VALUES_PER_FACET};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::{Map, Value};
|
use serde_json::{Map, Value};
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
@ -146,7 +146,7 @@ impl Index {
|
|||||||
let criteria = self
|
let criteria = self
|
||||||
.criteria(txn)?
|
.criteria(txn)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|c| c.to_string())
|
.map(|c| AscDesc::Asc(Member::Field("todo".to_string())))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let stop_words = self
|
let stop_words = self
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
use std::collections::{BTreeMap, BTreeSet};
|
use jayson::DeserializeFromValue;
|
||||||
use std::marker::PhantomData;
|
|
||||||
use std::num::NonZeroUsize;
|
|
||||||
|
|
||||||
use log::{debug, info, trace};
|
use log::{debug, info, trace};
|
||||||
use milli::documents::DocumentBatchReader;
|
use milli::documents::DocumentBatchReader;
|
||||||
use milli::update::{
|
use milli::update::{
|
||||||
DocumentAdditionResult, DocumentDeletionResult, IndexDocumentsConfig, IndexDocumentsMethod,
|
DocumentAdditionResult, DocumentDeletionResult, IndexDocumentsConfig, IndexDocumentsMethod,
|
||||||
Setting,
|
Setting,
|
||||||
};
|
};
|
||||||
|
use milli::{AscDesc, Criterion};
|
||||||
|
use rayon::vec;
|
||||||
use serde::{Deserialize, Serialize, Serializer};
|
use serde::{Deserialize, Serialize, Serializer};
|
||||||
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
use std::num::NonZeroUsize;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use super::error::Result;
|
use super::error::Result;
|
||||||
@ -36,9 +38,23 @@ pub struct Checked;
|
|||||||
|
|
||||||
#[derive(Clone, Default, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Clone, Default, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct Unchecked;
|
pub struct Unchecked;
|
||||||
|
impl<E> DeserializeFromValue<E> for Unchecked
|
||||||
|
where
|
||||||
|
E: jayson::DeserializeError,
|
||||||
|
{
|
||||||
|
fn deserialize_from_value<V>(
|
||||||
|
value: jayson::Value<V>,
|
||||||
|
location: jayson::ValuePointerRef,
|
||||||
|
) -> std::result::Result<Self, E>
|
||||||
|
where
|
||||||
|
V: jayson::IntoValue,
|
||||||
|
{
|
||||||
|
Ok(Unchecked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, DeserializeFromValue)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct MinWordSizeTyposSetting {
|
pub struct MinWordSizeTyposSetting {
|
||||||
@ -51,7 +67,9 @@ pub struct MinWordSizeTyposSetting {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
|
#[derive(
|
||||||
|
Debug, Clone, Default, Serialize, Deserialize, PartialEq, jayson::DeserializeFromValue,
|
||||||
|
)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct TypoSettings {
|
pub struct TypoSettings {
|
||||||
@ -70,7 +88,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)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, DeserializeFromValue)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct FacetingSettings {
|
pub struct FacetingSettings {
|
||||||
@ -80,7 +98,9 @@ pub struct FacetingSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
|
#[derive(
|
||||||
|
Debug, Clone, Default, Serialize, Deserialize, PartialEq, jayson::DeserializeFromValue,
|
||||||
|
)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct PaginationSettings {
|
pub struct PaginationSettings {
|
||||||
@ -92,11 +112,15 @@ pub struct PaginationSettings {
|
|||||||
/// Holds all the settings for an index. `T` can either be `Checked` if they represents settings
|
/// Holds all the settings for an index. `T` can either be `Checked` if they represents settings
|
||||||
/// whose validity is guaranteed, or `Unchecked` if they need to be validated. In the later case, a
|
/// whose validity is guaranteed, or `Unchecked` if they need to be validated. In the later case, a
|
||||||
/// call to `check` will return a `Settings<Checked>` from a `Settings<Unchecked>`.
|
/// call to `check` will return a `Settings<Checked>` from a `Settings<Unchecked>`.
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
|
|
||||||
|
#[derive(
|
||||||
|
Debug, Clone, Default, Serialize, Deserialize, PartialEq, jayson::DeserializeFromValue,
|
||||||
|
)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
#[serde(bound(serialize = "T: Serialize", deserialize = "T: Deserialize<'static>"))]
|
#[serde(bound(serialize = "T: Serialize", deserialize = "T: Deserialize<'static>"))]
|
||||||
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
|
||||||
|
#[jayson(rename_all = camelCase, deny_unknown_fields)]
|
||||||
pub struct Settings<T> {
|
pub struct Settings<T> {
|
||||||
#[serde(
|
#[serde(
|
||||||
default,
|
default,
|
||||||
@ -122,7 +146,8 @@ pub struct Settings<T> {
|
|||||||
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::setting_strategy()"))]
|
||||||
pub ranking_rules: Setting<Vec<String>>,
|
#[jayson(needs_predicate)]
|
||||||
|
pub ranking_rules: Setting<Vec<AscDesc>>,
|
||||||
#[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::setting_strategy()"))]
|
||||||
pub stop_words: Setting<BTreeSet<String>>,
|
pub stop_words: Setting<BTreeSet<String>>,
|
||||||
|
@ -10,6 +10,8 @@ proptest = { version = "1.0.0", optional = true }
|
|||||||
proptest-derive = { version = "0.3.0", optional = true }
|
proptest-derive = { version = "0.3.0", optional = true }
|
||||||
serde = { version = "1.0.136", features = ["derive"] }
|
serde = { version = "1.0.136", features = ["derive"] }
|
||||||
serde_json = "1.0.79"
|
serde_json = "1.0.79"
|
||||||
|
jayson = { path = "../../jayson" }
|
||||||
|
milli = { path = "../../milli/milli" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
test-traits = ["proptest", "proptest-derive"]
|
test-traits = ["proptest", "proptest-derive"]
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use actix_web::{self as aweb, http::StatusCode, HttpResponseBuilder};
|
use actix_web::{self as aweb, http::StatusCode, HttpResponseBuilder};
|
||||||
|
use jayson::{ValueKind, ValuePointerRef};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||||
@ -22,6 +23,84 @@ pub struct ResponseError {
|
|||||||
error_link: String,
|
error_link: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct MeiliDeserError(String);
|
||||||
|
impl std::fmt::Display for MeiliDeserError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "{}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl std::error::Error for MeiliDeserError {}
|
||||||
|
impl ErrorCode for MeiliDeserError {
|
||||||
|
fn error_code(&self) -> Code {
|
||||||
|
Code::MalformedPayload
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl jayson::MergeWithError<milli::AscDescError> for MeiliDeserError {
|
||||||
|
fn merge(
|
||||||
|
self_: Option<Self>,
|
||||||
|
other: milli::AscDescError,
|
||||||
|
merge_location: jayson::ValuePointerRef,
|
||||||
|
) -> Result<Self, Self> {
|
||||||
|
let pointer = merge_location.to_owned();
|
||||||
|
Err(MeiliDeserError(format!("{pointer:?} -> {other} ")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl jayson::MergeWithError<MeiliDeserError> for MeiliDeserError {
|
||||||
|
fn merge(
|
||||||
|
self_: Option<Self>,
|
||||||
|
other: MeiliDeserError,
|
||||||
|
merge_location: ValuePointerRef,
|
||||||
|
) -> Result<Self, Self> {
|
||||||
|
Err(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl jayson::DeserializeError for MeiliDeserError {
|
||||||
|
/// Return the origin of the error, if it can be found
|
||||||
|
fn location(&self) -> Option<jayson::ValuePointer> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
/// Create a new error due to an unexpected value kind.
|
||||||
|
///
|
||||||
|
/// Return `Ok` to continue deserializing or `Err` to fail early.
|
||||||
|
fn incorrect_value_kind(
|
||||||
|
self_: Option<Self>,
|
||||||
|
actual: ValueKind,
|
||||||
|
accepted: &[ValueKind],
|
||||||
|
location: ValuePointerRef,
|
||||||
|
) -> Result<Self, Self> {
|
||||||
|
Err(MeiliDeserError(format!("incorrect value kind {actual}")))
|
||||||
|
}
|
||||||
|
/// Create a new error due to a missing key.
|
||||||
|
///
|
||||||
|
/// Return `Ok` to continue deserializing or `Err` to fail early.
|
||||||
|
fn missing_field(
|
||||||
|
self_: Option<Self>,
|
||||||
|
field: &str,
|
||||||
|
location: ValuePointerRef,
|
||||||
|
) -> Result<Self, Self> {
|
||||||
|
Err(MeiliDeserError(format!("missing field {field}")))
|
||||||
|
}
|
||||||
|
/// Create a new error due to finding an unknown key.
|
||||||
|
///
|
||||||
|
/// Return `Ok` to continue deserializing or `Err` to fail early.
|
||||||
|
fn unknown_key(
|
||||||
|
self_: Option<Self>,
|
||||||
|
key: &str,
|
||||||
|
accepted: &[&str],
|
||||||
|
location: ValuePointerRef,
|
||||||
|
) -> Result<Self, Self> {
|
||||||
|
Err(MeiliDeserError(format!("unknown key {key}")))
|
||||||
|
}
|
||||||
|
/// Create a new error with the custom message.
|
||||||
|
///
|
||||||
|
/// Return `Ok` to continue deserializing or `Err` to fail early.
|
||||||
|
fn unexpected(self_: Option<Self>, msg: &str, location: ValuePointerRef) -> Result<Self, Self> {
|
||||||
|
Err(MeiliDeserError(format!("unexpected {msg}")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ResponseError {
|
impl ResponseError {
|
||||||
pub fn from_msg(message: String, code: Code) -> Self {
|
pub fn from_msg(message: String, code: Code) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
Loading…
Reference in New Issue
Block a user