bump deserr

This commit is contained in:
Tamo 2023-02-13 18:45:13 +01:00
parent f3b54337f9
commit 8fb7b1d10f
No known key found for this signature in database
GPG Key ID: 20CD8020AFA88D69
23 changed files with 137 additions and 102 deletions

53
Cargo.lock generated
View File

@ -36,9 +36,9 @@ dependencies = [
[[package]] [[package]]
name = "actix-http" name = "actix-http"
version = "3.2.2" version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c83abf9903e1f0ad9973cc4f7b9767fd5a03a583f51a5b7a339e07987cd2724" checksum = "0070905b2c4a98d184c4e81025253cb192aa8a73827553f38e9410801ceb35bb"
dependencies = [ dependencies = [
"actix-codec", "actix-codec",
"actix-rt", "actix-rt",
@ -46,7 +46,7 @@ dependencies = [
"actix-tls", "actix-tls",
"actix-utils", "actix-utils",
"ahash", "ahash",
"base64 0.13.1", "base64 0.21.0",
"bitflags", "bitflags",
"brotli", "brotli",
"bytes", "bytes",
@ -68,7 +68,10 @@ dependencies = [
"rand", "rand",
"sha1", "sha1",
"smallvec", "smallvec",
"tokio",
"tokio-util",
"tracing", "tracing",
"zstd 0.12.3+zstd.1.5.2",
] ]
[[package]] [[package]]
@ -164,9 +167,9 @@ dependencies = [
[[package]] [[package]]
name = "actix-web" name = "actix-web"
version = "4.2.1" version = "4.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d48f7b6534e06c7bfc72ee91db7917d4af6afe23e7d223b51e68fffbb21e96b9" checksum = "464e0fddc668ede5f26ec1f9557a8d44eda948732f40c6b0ad79126930eb775f"
dependencies = [ dependencies = [
"actix-codec", "actix-codec",
"actix-http", "actix-http",
@ -1110,20 +1113,23 @@ dependencies = [
[[package]] [[package]]
name = "deserr" name = "deserr"
version = "0.3.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28380303ca15ec07e1d5b079baf19cf849b09edad5cab219c1c51b2bd07523de" checksum = "a13eed41ca58d9dc99e2c67e1a5f50507dfa1b123cc4a942c81c49707bd347f0"
dependencies = [ dependencies = [
"actix-web",
"deserr-internal", "deserr-internal",
"futures",
"serde-cs", "serde-cs",
"serde_json", "serde_json",
"strsim",
] ]
[[package]] [[package]]
name = "deserr-internal" name = "deserr-internal"
version = "0.3.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "860928cd8af78d223a3d70dd581f21d7c3de8aa2eecd938e0c0a399ded7c1451" checksum = "4d5412186d7149542b09319901d28b3c7d1f714a61d0c5d48a50560d09573ae4"
dependencies = [ dependencies = [
"convert_case 0.5.0", "convert_case 0.5.0",
"proc-macro2", "proc-macro2",
@ -4423,7 +4429,7 @@ dependencies = [
"pbkdf2", "pbkdf2",
"sha1", "sha1",
"time", "time",
"zstd", "zstd 0.11.2+zstd.1.5.2",
] ]
[[package]] [[package]]
@ -4432,7 +4438,16 @@ version = "0.11.2+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4"
dependencies = [ dependencies = [
"zstd-safe", "zstd-safe 5.0.2+zstd.1.5.2",
]
[[package]]
name = "zstd"
version = "0.12.3+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76eea132fb024e0e13fd9c2f5d5d595d8a967aa72382ac2f9d39fcc95afd0806"
dependencies = [
"zstd-safe 6.0.4+zstd.1.5.4",
] ]
[[package]] [[package]]
@ -4446,10 +4461,20 @@ dependencies = [
] ]
[[package]] [[package]]
name = "zstd-sys" name = "zstd-safe"
version = "2.0.5+zstd.1.5.2" version = "6.0.4+zstd.1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edc50ffce891ad571e9f9afe5039c4837bede781ac4bb13052ed7ae695518596" checksum = "7afb4b54b8910cf5447638cb54bf4e8a65cbedd783af98b98c62ffe91f185543"
dependencies = [
"libc",
"zstd-sys",
]
[[package]]
name = "zstd-sys"
version = "2.0.7+zstd.1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94509c3ba2fe55294d752b79842c530ccfab760192521df74a081a78d2b3c7f5"
dependencies = [ dependencies = [
"cc", "cc",
"libc", "libc",

View File

@ -9,7 +9,7 @@ actix-web = { version = "4.2.1", default-features = false }
anyhow = "1.0.65" anyhow = "1.0.65"
convert_case = "0.6.0" convert_case = "0.6.0"
csv = "1.1.6" csv = "1.1.6"
deserr = "0.3.0" deserr = "0.4.0"
either = { version = "1.6.1", features = ["serde"] } either = { version = "1.6.1", features = ["serde"] }
enum-iterator = "1.1.3" enum-iterator = "1.1.3"
file-store = { path = "../file-store" } file-store = { path = "../file-store" }

View File

@ -6,6 +6,8 @@ We try to:
2. Use the correct terms depending on the format of the request (json/query param) 2. Use the correct terms depending on the format of the request (json/query param)
3. Categorise the type of the error (e.g. missing field, wrong value type, unexpected error, etc.) 3. Categorise the type of the error (e.g. missing field, wrong value type, unexpected error, etc.)
*/ */
use std::ops::ControlFlow;
use deserr::{ErrorKind, IntoValue, ValueKind, ValuePointerRef}; use deserr::{ErrorKind, IntoValue, ValueKind, ValuePointerRef};
use super::{DeserrJsonError, DeserrQueryParamError}; use super::{DeserrJsonError, DeserrQueryParamError};
@ -129,7 +131,7 @@ impl<C: Default + ErrorCode> deserr::DeserializeError for DeserrJsonError<C> {
_self_: Option<Self>, _self_: Option<Self>,
error: deserr::ErrorKind<V>, error: deserr::ErrorKind<V>,
location: ValuePointerRef, location: ValuePointerRef,
) -> Result<Self, Self> { ) -> ControlFlow<Self, Self> {
let mut message = String::new(); let mut message = String::new();
message.push_str(&match error { message.push_str(&match error {
@ -175,7 +177,7 @@ impl<C: Default + ErrorCode> deserr::DeserializeError for DeserrJsonError<C> {
} }
}); });
Err(DeserrJsonError::new(message, C::default().error_code())) ControlFlow::Break(DeserrJsonError::new(message, C::default().error_code()))
} }
} }
@ -222,7 +224,7 @@ impl<C: Default + ErrorCode> deserr::DeserializeError for DeserrQueryParamError<
_self_: Option<Self>, _self_: Option<Self>,
error: deserr::ErrorKind<V>, error: deserr::ErrorKind<V>,
location: ValuePointerRef, location: ValuePointerRef,
) -> Result<Self, Self> { ) -> ControlFlow<Self, Self> {
let mut message = String::new(); let mut message = String::new();
message.push_str(&match error { message.push_str(&match error {
@ -268,7 +270,7 @@ impl<C: Default + ErrorCode> deserr::DeserializeError for DeserrQueryParamError<
} }
}); });
Err(DeserrQueryParamError::new(message, C::default().error_code())) ControlFlow::Break(DeserrQueryParamError::new(message, C::default().error_code()))
} }
} }

View File

@ -1,6 +1,7 @@
use std::convert::Infallible; use std::convert::Infallible;
use std::fmt; use std::fmt;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ops::ControlFlow;
use deserr::{DeserializeError, MergeWithError, ValuePointerRef}; use deserr::{DeserializeError, MergeWithError, ValuePointerRef};
@ -64,8 +65,8 @@ impl<Format, C1: Default + ErrorCode, C2: Default + ErrorCode>
_self_: Option<Self>, _self_: Option<Self>,
other: DeserrError<Format, C2>, other: DeserrError<Format, C2>,
_merge_location: ValuePointerRef, _merge_location: ValuePointerRef,
) -> Result<Self, Self> { ) -> ControlFlow<Self, Self> {
Err(DeserrError { msg: other.msg, code: other.code, _phantom: PhantomData }) ControlFlow::Break(DeserrError { msg: other.msg, code: other.code, _phantom: PhantomData })
} }
} }
@ -74,7 +75,7 @@ impl<Format, C: Default + ErrorCode> MergeWithError<Infallible> for DeserrError<
_self_: Option<Self>, _self_: Option<Self>,
_other: Infallible, _other: Infallible,
_merge_location: ValuePointerRef, _merge_location: ValuePointerRef,
) -> Result<Self, Self> { ) -> ControlFlow<Self, Self> {
unreachable!() unreachable!()
} }
} }
@ -112,7 +113,7 @@ macro_rules! merge_with_error_impl_take_error_message {
_self_: Option<Self>, _self_: Option<Self>,
other: $err_type, other: $err_type,
merge_location: ValuePointerRef, merge_location: ValuePointerRef,
) -> Result<Self, Self> { ) -> ControlFlow<Self, Self> {
DeserrError::<Format, C>::error::<Infallible>( DeserrError::<Format, C>::error::<Infallible>(
None, None,
deserr::ErrorKind::Unexpected { msg: other.to_string() }, deserr::ErrorKind::Unexpected { msg: other.to_string() },

View File

@ -15,7 +15,7 @@ use std::convert::Infallible;
use std::ops::Deref; use std::ops::Deref;
use std::str::FromStr; use std::str::FromStr;
use deserr::{DeserializeError, DeserializeFromValue, MergeWithError, ValueKind}; use deserr::{DeserializeError, Deserr, MergeWithError, ValueKind};
use super::{DeserrParseBoolError, DeserrParseIntError}; use super::{DeserrParseBoolError, DeserrParseIntError};
use crate::error::unwrap_any; use crate::error::unwrap_any;
@ -38,7 +38,7 @@ impl<T> Deref for Param<T> {
} }
} }
impl<T, E> DeserializeFromValue<E> for Param<T> impl<T, E> Deserr<E> for Param<T>
where where
E: DeserializeError + MergeWithError<T::Err>, E: DeserializeError + MergeWithError<T::Err>,
T: FromQueryParameter, T: FromQueryParameter,

View File

@ -382,10 +382,12 @@ impl ErrorCode for io::Error {
} }
/// Unwrap a result, either its Ok or Err value. /// Unwrap a result, either its Ok or Err value.
pub fn unwrap_any<T>(any: Result<T, T>) -> T { pub fn unwrap_any<T>(any: std::ops::ControlFlow<T, T>) -> T {
use std::ops::ControlFlow::*;
match any { match any {
Ok(any) => any, Continue(any) => any,
Err(any) => any, Break(any) => any,
} }
} }

View File

@ -2,14 +2,14 @@ use std::error::Error;
use std::fmt; use std::fmt;
use std::str::FromStr; use std::str::FromStr;
use deserr::DeserializeFromValue; use deserr::Deserr;
use crate::error::{Code, ErrorCode}; use crate::error::{Code, ErrorCode};
/// An index uid is composed of only ascii alphanumeric characters, - and _, between 1 and 400 /// An index uid is composed of only ascii alphanumeric characters, - and _, between 1 and 400
/// bytes long /// bytes long
#[derive(Debug, Clone, PartialEq, Eq, DeserializeFromValue)] #[derive(Debug, Clone, PartialEq, Eq, Deserr)]
#[deserr(from(String) = IndexUid::try_from -> IndexUidFormatError)] #[deserr(try_from(String) = IndexUid::try_from -> IndexUidFormatError)]
pub struct IndexUid(String); pub struct IndexUid(String);
impl IndexUid { impl IndexUid {

View File

@ -4,7 +4,7 @@ use std::fmt;
use std::ops::Deref; use std::ops::Deref;
use std::str::FromStr; use std::str::FromStr;
use deserr::DeserializeFromValue; use deserr::Deserr;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::error::{Code, ErrorCode}; use crate::error::{Code, ErrorCode};
@ -12,8 +12,8 @@ use crate::index_uid::{IndexUid, IndexUidFormatError};
/// An index uid pattern is composed of only ascii alphanumeric characters, - and _, between 1 and 400 /// An index uid pattern is composed of only ascii alphanumeric characters, - and _, between 1 and 400
/// bytes long and optionally ending with a *. /// bytes long and optionally ending with a *.
#[derive(Serialize, Deserialize, DeserializeFromValue, Debug, Clone, PartialEq, Eq, Hash)] #[derive(Serialize, Deserialize, Deserr, Debug, Clone, PartialEq, Eq, Hash)]
#[deserr(from(&String) = FromStr::from_str -> IndexUidPatternFormatError)] #[deserr(try_from(&String) = FromStr::from_str -> IndexUidPatternFormatError)]
pub struct IndexUidPattern(String); pub struct IndexUidPattern(String);
impl IndexUidPattern { impl IndexUidPattern {

View File

@ -2,7 +2,7 @@ use std::convert::Infallible;
use std::hash::Hash; use std::hash::Hash;
use std::str::FromStr; use std::str::FromStr;
use deserr::{DeserializeError, DeserializeFromValue, MergeWithError, ValuePointerRef}; use deserr::{DeserializeError, Deserr, MergeWithError, ValuePointerRef};
use enum_iterator::Sequence; use enum_iterator::Sequence;
use milli::update::Setting; use milli::update::Setting;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -24,7 +24,7 @@ impl<C: Default + ErrorCode> MergeWithError<IndexUidPatternFormatError> for Dese
_self_: Option<Self>, _self_: Option<Self>,
other: IndexUidPatternFormatError, other: IndexUidPatternFormatError,
merge_location: deserr::ValuePointerRef, merge_location: deserr::ValuePointerRef,
) -> std::result::Result<Self, Self> { ) -> std::ops::ControlFlow<Self, Self> {
DeserrError::error::<Infallible>( DeserrError::error::<Infallible>(
None, None,
deserr::ErrorKind::Unexpected { msg: other.to_string() }, deserr::ErrorKind::Unexpected { msg: other.to_string() },
@ -33,20 +33,20 @@ impl<C: Default + ErrorCode> MergeWithError<IndexUidPatternFormatError> for Dese
} }
} }
#[derive(Debug, DeserializeFromValue)] #[derive(Debug, Deserr)]
#[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)] #[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)]
pub struct CreateApiKey { pub struct CreateApiKey {
#[deserr(default, error = DeserrJsonError<InvalidApiKeyDescription>)] #[deserr(default, error = DeserrJsonError<InvalidApiKeyDescription>)]
pub description: Option<String>, pub description: Option<String>,
#[deserr(default, error = DeserrJsonError<InvalidApiKeyName>)] #[deserr(default, error = DeserrJsonError<InvalidApiKeyName>)]
pub name: Option<String>, pub name: Option<String>,
#[deserr(default = Uuid::new_v4(), error = DeserrJsonError<InvalidApiKeyUid>, from(&String) = Uuid::from_str -> uuid::Error)] #[deserr(default = Uuid::new_v4(), error = DeserrJsonError<InvalidApiKeyUid>, try_from(&String) = Uuid::from_str -> uuid::Error)]
pub uid: KeyId, pub uid: KeyId,
#[deserr(error = DeserrJsonError<InvalidApiKeyActions>, missing_field_error = DeserrJsonError::missing_api_key_actions)] #[deserr(error = DeserrJsonError<InvalidApiKeyActions>, missing_field_error = DeserrJsonError::missing_api_key_actions)]
pub actions: Vec<Action>, pub actions: Vec<Action>,
#[deserr(error = DeserrJsonError<InvalidApiKeyIndexes>, missing_field_error = DeserrJsonError::missing_api_key_indexes)] #[deserr(error = DeserrJsonError<InvalidApiKeyIndexes>, missing_field_error = DeserrJsonError::missing_api_key_indexes)]
pub indexes: Vec<IndexUidPattern>, pub indexes: Vec<IndexUidPattern>,
#[deserr(error = DeserrJsonError<InvalidApiKeyExpiresAt>, from(Option<String>) = parse_expiration_date -> ParseOffsetDateTimeError, missing_field_error = DeserrJsonError::missing_api_key_expires_at)] #[deserr(error = DeserrJsonError<InvalidApiKeyExpiresAt>, try_from(Option<String>) = parse_expiration_date -> ParseOffsetDateTimeError, missing_field_error = DeserrJsonError::missing_api_key_expires_at)]
pub expires_at: Option<OffsetDateTime>, pub expires_at: Option<OffsetDateTime>,
} }
@ -87,7 +87,7 @@ fn deny_immutable_fields_api_key(
} }
} }
#[derive(Debug, DeserializeFromValue)] #[derive(Debug, Deserr)]
#[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields = deny_immutable_fields_api_key)] #[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields = deny_immutable_fields_api_key)]
pub struct PatchApiKey { pub struct PatchApiKey {
#[deserr(default, error = DeserrJsonError<InvalidApiKeyDescription>)] #[deserr(default, error = DeserrJsonError<InvalidApiKeyDescription>)]
@ -182,9 +182,7 @@ fn parse_expiration_date(
} }
} }
#[derive( #[derive(Copy, Clone, Serialize, Deserialize, Debug, Eq, PartialEq, Hash, Sequence, Deserr)]
Copy, Clone, Serialize, Deserialize, Debug, Eq, PartialEq, Hash, Sequence, DeserializeFromValue,
)]
#[repr(u8)] #[repr(u8)]
pub enum Action { pub enum Action {
#[serde(rename = "*")] #[serde(rename = "*")]

View File

@ -3,9 +3,10 @@ use std::convert::Infallible;
use std::fmt; use std::fmt;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::num::NonZeroUsize; use std::num::NonZeroUsize;
use std::ops::ControlFlow;
use std::str::FromStr; use std::str::FromStr;
use deserr::{DeserializeError, DeserializeFromValue, ErrorKind, MergeWithError, ValuePointerRef}; use deserr::{DeserializeError, Deserr, ErrorKind, MergeWithError, ValuePointerRef};
use fst::IntoStreamer; use fst::IntoStreamer;
use milli::update::Setting; use milli::update::Setting;
use milli::{Criterion, CriterionError, Index, DEFAULT_VALUES_PER_FACET}; use milli::{Criterion, CriterionError, Index, DEFAULT_VALUES_PER_FACET};
@ -41,7 +42,7 @@ pub struct Checked;
#[derive(Clone, Default, Debug, Serialize, Deserialize, PartialEq, Eq)] #[derive(Clone, Default, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct Unchecked; pub struct Unchecked;
impl<E> DeserializeFromValue<E> for Unchecked impl<E> Deserr<E> for Unchecked
where where
E: DeserializeError, E: DeserializeError,
{ {
@ -65,7 +66,7 @@ fn validate_min_word_size_for_typo_setting<E: DeserializeError>(
Ok(s) Ok(s)
} }
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq, DeserializeFromValue)] #[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq, Deserr)]
#[serde(deny_unknown_fields, rename_all = "camelCase")] #[serde(deny_unknown_fields, rename_all = "camelCase")]
#[deserr(deny_unknown_fields, rename_all = camelCase, validate = validate_min_word_size_for_typo_setting -> DeserrJsonError<InvalidSettingsTypoTolerance>)] #[deserr(deny_unknown_fields, rename_all = camelCase, validate = validate_min_word_size_for_typo_setting -> DeserrJsonError<InvalidSettingsTypoTolerance>)]
pub struct MinWordSizeTyposSetting { pub struct MinWordSizeTyposSetting {
@ -77,7 +78,7 @@ pub struct MinWordSizeTyposSetting {
pub two_typos: Setting<u8>, pub two_typos: Setting<u8>,
} }
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq, DeserializeFromValue)] #[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq, Deserr)]
#[serde(deny_unknown_fields, rename_all = "camelCase")] #[serde(deny_unknown_fields, rename_all = "camelCase")]
#[deserr(deny_unknown_fields, rename_all = camelCase, where_predicate = __Deserr_E: deserr::MergeWithError<DeserrJsonError<InvalidSettingsTypoTolerance>>)] #[deserr(deny_unknown_fields, rename_all = camelCase, where_predicate = __Deserr_E: deserr::MergeWithError<DeserrJsonError<InvalidSettingsTypoTolerance>>)]
pub struct TypoSettings { pub struct TypoSettings {
@ -95,7 +96,7 @@ pub struct TypoSettings {
pub disable_on_attributes: Setting<BTreeSet<String>>, pub disable_on_attributes: Setting<BTreeSet<String>>,
} }
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq, DeserializeFromValue)] #[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq, Deserr)]
#[serde(deny_unknown_fields, rename_all = "camelCase")] #[serde(deny_unknown_fields, rename_all = "camelCase")]
#[deserr(rename_all = camelCase, deny_unknown_fields)] #[deserr(rename_all = camelCase, deny_unknown_fields)]
pub struct FacetingSettings { pub struct FacetingSettings {
@ -104,7 +105,7 @@ pub struct FacetingSettings {
pub max_values_per_facet: Setting<usize>, pub max_values_per_facet: Setting<usize>,
} }
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq, DeserializeFromValue)] #[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq, Deserr)]
#[serde(deny_unknown_fields, rename_all = "camelCase")] #[serde(deny_unknown_fields, rename_all = "camelCase")]
#[deserr(rename_all = camelCase, deny_unknown_fields)] #[deserr(rename_all = camelCase, deny_unknown_fields)]
pub struct PaginationSettings { pub struct PaginationSettings {
@ -118,7 +119,7 @@ impl MergeWithError<milli::CriterionError> for DeserrJsonError<InvalidSettingsRa
_self_: Option<Self>, _self_: Option<Self>,
other: milli::CriterionError, other: milli::CriterionError,
merge_location: ValuePointerRef, merge_location: ValuePointerRef,
) -> Result<Self, Self> { ) -> ControlFlow<Self, Self> {
Self::error::<Infallible>( Self::error::<Infallible>(
None, None,
ErrorKind::Unexpected { msg: other.to_string() }, ErrorKind::Unexpected { msg: other.to_string() },
@ -130,7 +131,7 @@ impl MergeWithError<milli::CriterionError> for DeserrJsonError<InvalidSettingsRa
/// 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, Eq, DeserializeFromValue)] #[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq, Deserr)]
#[serde( #[serde(
deny_unknown_fields, deny_unknown_fields,
rename_all = "camelCase", rename_all = "camelCase",
@ -509,8 +510,8 @@ pub fn settings(
}) })
} }
#[derive(Debug, Clone, PartialEq, Eq, DeserializeFromValue)] #[derive(Debug, Clone, PartialEq, Eq, Deserr)]
#[deserr(from(&String) = FromStr::from_str -> CriterionError)] #[deserr(try_from(&String) = FromStr::from_str -> CriterionError)]
pub enum RankingRuleView { pub enum RankingRuleView {
/// Sorted by decreasing number of matched query terms. /// Sorted by decreasing number of matched query terms.
/// Query words at the front of an attribute is considered better than if it was at the back. /// Query words at the front of an attribute is considered better than if it was at the back.

View File

@ -1,8 +1,9 @@
use std::fmt; use std::fmt;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ops::ControlFlow;
use std::str::FromStr; use std::str::FromStr;
use deserr::{DeserializeError, DeserializeFromValue, MergeWithError, ValueKind}; use deserr::{DeserializeError, Deserr, MergeWithError, ValueKind};
use serde::de::Visitor; use serde::de::Visitor;
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
@ -111,7 +112,7 @@ where
} }
} }
impl<T, E> DeserializeFromValue<E> for StarOr<T> impl<T, E> Deserr<E> for StarOr<T>
where where
T: FromStr, T: FromStr,
E: DeserializeError + MergeWithError<T::Err>, E: DeserializeError + MergeWithError<T::Err>,
@ -191,7 +192,7 @@ where
} }
} }
impl<T, E> DeserializeFromValue<E> for OptionStarOr<T> impl<T, E> Deserr<E> for OptionStarOr<T>
where where
E: DeserializeError + MergeWithError<T::Err>, E: DeserializeError + MergeWithError<T::Err>,
T: FromQueryParameter, T: FromQueryParameter,
@ -271,7 +272,7 @@ impl<T> OptionStarOrList<T> {
} }
} }
impl<T, E> DeserializeFromValue<E> for OptionStarOrList<T> impl<T, E> Deserr<E> for OptionStarOrList<T>
where where
E: DeserializeError + MergeWithError<T::Err>, E: DeserializeError + MergeWithError<T::Err>,
T: FromQueryParameter, T: FromQueryParameter,
@ -299,7 +300,10 @@ where
Err(e) => { Err(e) => {
let location = let location =
if len_cs > 1 { location.push_index(i) } else { location }; if len_cs > 1 { location.push_index(i) } else { location };
error = Some(E::merge(error, e, location)?); error = match E::merge(error, e, location) {
ControlFlow::Continue(e) => Some(e),
ControlFlow::Break(e) => return Err(e),
};
} }
} }
} }

View File

@ -19,7 +19,7 @@ byte-unit = { version = "4.0.14", default-features = false, features = ["std", "
bytes = "1.2.1" bytes = "1.2.1"
clap = { version = "4.0.9", features = ["derive", "env"] } clap = { version = "4.0.9", features = ["derive", "env"] }
crossbeam-channel = "0.5.6" crossbeam-channel = "0.5.6"
deserr = "0.3.0" deserr = "0.4.0"
dump = { path = "../dump" } dump = { path = "../dump" }
either = "1.8.0" either = "1.8.0"
env_logger = "0.9.1" env_logger = "0.9.1"

View File

@ -7,7 +7,7 @@ use std::task::{Context, Poll};
use actix_web::dev::Payload; use actix_web::dev::Payload;
use actix_web::web::Json; use actix_web::web::Json;
use actix_web::{FromRequest, HttpRequest}; use actix_web::{FromRequest, HttpRequest};
use deserr::{DeserializeError, DeserializeFromValue}; use deserr::{DeserializeError, Deserr};
use futures::ready; use futures::ready;
use meilisearch_types::error::{ErrorCode, ResponseError}; use meilisearch_types::error::{ErrorCode, ResponseError};
@ -33,7 +33,7 @@ impl<T, E> ValidatedJson<T, E> {
impl<T, E> FromRequest for ValidatedJson<T, E> impl<T, E> FromRequest for ValidatedJson<T, E>
where where
E: DeserializeError + ErrorCode + std::error::Error + 'static, E: DeserializeError + ErrorCode + std::error::Error + 'static,
T: DeserializeFromValue<E>, T: Deserr<E>,
{ {
type Error = actix_web::Error; type Error = actix_web::Error;
type Future = ValidatedJsonExtractFut<T, E>; type Future = ValidatedJsonExtractFut<T, E>;
@ -54,7 +54,7 @@ pub struct ValidatedJsonExtractFut<T, E> {
impl<T, E> Future for ValidatedJsonExtractFut<T, E> impl<T, E> Future for ValidatedJsonExtractFut<T, E>
where where
T: DeserializeFromValue<E>, T: Deserr<E>,
E: DeserializeError + ErrorCode + std::error::Error + 'static, E: DeserializeError + ErrorCode + std::error::Error + 'static,
{ {
type Output = Result<ValidatedJson<T, E>, actix_web::Error>; type Output = Result<ValidatedJson<T, E>, actix_web::Error>;

View File

@ -6,7 +6,7 @@ use std::{fmt, ops};
use actix_http::Payload; use actix_http::Payload;
use actix_utils::future::{err, ok, Ready}; use actix_utils::future::{err, ok, Ready};
use actix_web::{FromRequest, HttpRequest}; use actix_web::{FromRequest, HttpRequest};
use deserr::{DeserializeError, DeserializeFromValue}; use deserr::{DeserializeError, Deserr};
use meilisearch_types::error::{Code, ErrorCode, ResponseError}; use meilisearch_types::error::{Code, ErrorCode, ResponseError};
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
@ -21,7 +21,7 @@ impl<T, E> QueryParameter<T, E> {
impl<T, E> QueryParameter<T, E> impl<T, E> QueryParameter<T, E>
where where
T: DeserializeFromValue<E>, T: Deserr<E>,
E: DeserializeError + ErrorCode + std::error::Error + 'static, E: DeserializeError + ErrorCode + std::error::Error + 'static,
{ {
pub fn from_query(query_str: &str) -> Result<Self, actix_web::Error> { pub fn from_query(query_str: &str) -> Result<Self, actix_web::Error> {
@ -57,7 +57,7 @@ impl<T: fmt::Display, E> fmt::Display for QueryParameter<T, E> {
impl<T, E> FromRequest for QueryParameter<T, E> impl<T, E> FromRequest for QueryParameter<T, E>
where where
T: DeserializeFromValue<E>, T: Deserr<E>,
E: DeserializeError + ErrorCode + std::error::Error + 'static, E: DeserializeError + ErrorCode + std::error::Error + 'static,
{ {
type Error = actix_web::Error; type Error = actix_web::Error;

View File

@ -1,7 +1,7 @@
use std::str; use std::str;
use actix_web::{web, HttpRequest, HttpResponse}; use actix_web::{web, HttpRequest, HttpResponse};
use deserr::DeserializeFromValue; use deserr::Deserr;
use meilisearch_auth::error::AuthControllerError; use meilisearch_auth::error::AuthControllerError;
use meilisearch_auth::AuthController; use meilisearch_auth::AuthController;
use meilisearch_types::deserr::query_params::Param; use meilisearch_types::deserr::query_params::Param;
@ -51,7 +51,7 @@ pub async fn create_api_key(
Ok(HttpResponse::Created().json(res)) Ok(HttpResponse::Created().json(res))
} }
#[derive(DeserializeFromValue, Debug, Clone, Copy)] #[derive(Deserr, Debug, Clone, Copy)]
#[deserr(error = DeserrQueryParamError, rename_all = camelCase, deny_unknown_fields)] #[deserr(error = DeserrQueryParamError, rename_all = camelCase, deny_unknown_fields)]
pub struct ListApiKeys { pub struct ListApiKeys {
#[deserr(default, error = DeserrQueryParamError<InvalidApiKeyOffset>)] #[deserr(default, error = DeserrQueryParamError<InvalidApiKeyOffset>)]

View File

@ -4,7 +4,7 @@ use actix_web::http::header::CONTENT_TYPE;
use actix_web::web::Data; use actix_web::web::Data;
use actix_web::{web, HttpMessage, HttpRequest, HttpResponse}; use actix_web::{web, HttpMessage, HttpRequest, HttpResponse};
use bstr::ByteSlice; use bstr::ByteSlice;
use deserr::DeserializeFromValue; use deserr::Deserr;
use futures::StreamExt; use futures::StreamExt;
use index_scheduler::IndexScheduler; use index_scheduler::IndexScheduler;
use log::debug; use log::debug;
@ -80,7 +80,7 @@ pub fn configure(cfg: &mut web::ServiceConfig) {
); );
} }
#[derive(Debug, DeserializeFromValue)] #[derive(Debug, Deserr)]
#[deserr(error = DeserrQueryParamError, rename_all = camelCase, deny_unknown_fields)] #[deserr(error = DeserrQueryParamError, rename_all = camelCase, deny_unknown_fields)]
pub struct GetDocument { pub struct GetDocument {
#[deserr(default, error = DeserrQueryParamError<InvalidDocumentFields>)] #[deserr(default, error = DeserrQueryParamError<InvalidDocumentFields>)]
@ -125,7 +125,7 @@ pub async fn delete_document(
Ok(HttpResponse::Accepted().json(task)) Ok(HttpResponse::Accepted().json(task))
} }
#[derive(Debug, DeserializeFromValue)] #[derive(Debug, Deserr)]
#[deserr(error = DeserrQueryParamError, rename_all = camelCase, deny_unknown_fields)] #[deserr(error = DeserrQueryParamError, rename_all = camelCase, deny_unknown_fields)]
pub struct BrowseQuery { pub struct BrowseQuery {
#[deserr(default, error = DeserrQueryParamError<InvalidDocumentOffset>)] #[deserr(default, error = DeserrQueryParamError<InvalidDocumentOffset>)]
@ -155,7 +155,7 @@ pub async fn get_all_documents(
Ok(HttpResponse::Ok().json(ret)) Ok(HttpResponse::Ok().json(ret))
} }
#[derive(Deserialize, Debug, DeserializeFromValue)] #[derive(Deserialize, Debug, Deserr)]
#[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)] #[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)]
pub struct UpdateDocumentsQuery { pub struct UpdateDocumentsQuery {
#[deserr(default, error = DeserrJsonError<InvalidIndexPrimaryKey>)] #[deserr(default, error = DeserrJsonError<InvalidIndexPrimaryKey>)]

View File

@ -2,7 +2,7 @@ use std::convert::Infallible;
use actix_web::web::Data; use actix_web::web::Data;
use actix_web::{web, HttpRequest, HttpResponse}; use actix_web::{web, HttpRequest, HttpResponse};
use deserr::{DeserializeError, DeserializeFromValue, ValuePointerRef}; use deserr::{DeserializeError, Deserr, ValuePointerRef};
use index_scheduler::IndexScheduler; use index_scheduler::IndexScheduler;
use log::debug; use log::debug;
use meilisearch_types::deserr::error_messages::immutable_field_error; use meilisearch_types::deserr::error_messages::immutable_field_error;
@ -73,7 +73,7 @@ impl IndexView {
} }
} }
#[derive(DeserializeFromValue, Debug, Clone, Copy)] #[derive(Deserr, Debug, Clone, Copy)]
#[deserr(error = DeserrQueryParamError, rename_all = camelCase, deny_unknown_fields)] #[deserr(error = DeserrQueryParamError, rename_all = camelCase, deny_unknown_fields)]
pub struct ListIndexes { pub struct ListIndexes {
#[deserr(default, error = DeserrQueryParamError<InvalidIndexOffset>)] #[deserr(default, error = DeserrQueryParamError<InvalidIndexOffset>)]
@ -105,7 +105,7 @@ pub async fn list_indexes(
Ok(HttpResponse::Ok().json(ret)) Ok(HttpResponse::Ok().json(ret))
} }
#[derive(DeserializeFromValue, Debug)] #[derive(Deserr, Debug)]
#[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)] #[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)]
pub struct IndexCreateRequest { pub struct IndexCreateRequest {
#[deserr(error = DeserrJsonError<InvalidIndexUid>, missing_field_error = DeserrJsonError::missing_index_uid)] #[deserr(error = DeserrJsonError<InvalidIndexUid>, missing_field_error = DeserrJsonError::missing_index_uid)]
@ -157,7 +157,7 @@ fn deny_immutable_fields_index(
} }
} }
#[derive(DeserializeFromValue, Debug)] #[derive(Deserr, Debug)]
#[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields = deny_immutable_fields_index)] #[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields = deny_immutable_fields_index)]
pub struct UpdateIndexRequest { pub struct UpdateIndexRequest {
#[deserr(default, error = DeserrJsonError<InvalidIndexPrimaryKey>)] #[deserr(default, error = DeserrJsonError<InvalidIndexPrimaryKey>)]

View File

@ -31,7 +31,7 @@ pub fn configure(cfg: &mut web::ServiceConfig) {
); );
} }
#[derive(Debug, deserr::DeserializeFromValue)] #[derive(Debug, deserr::Deserr)]
#[deserr(error = DeserrQueryParamError, rename_all = camelCase, deny_unknown_fields)] #[deserr(error = DeserrQueryParamError, rename_all = camelCase, deny_unknown_fields)]
pub struct SearchQueryGet { pub struct SearchQueryGet {
#[deserr(default, error = DeserrQueryParamError<InvalidSearchQ>)] #[deserr(default, error = DeserrQueryParamError<InvalidSearchQ>)]

View File

@ -1,6 +1,6 @@
use actix_web::web::Data; use actix_web::web::Data;
use actix_web::{web, HttpRequest, HttpResponse}; use actix_web::{web, HttpRequest, HttpResponse};
use deserr::DeserializeFromValue; use deserr::Deserr;
use index_scheduler::IndexScheduler; use index_scheduler::IndexScheduler;
use meilisearch_types::deserr::DeserrJsonError; use meilisearch_types::deserr::DeserrJsonError;
use meilisearch_types::error::deserr_codes::InvalidSwapIndexes; use meilisearch_types::error::deserr_codes::InvalidSwapIndexes;
@ -21,7 +21,7 @@ pub fn configure(cfg: &mut web::ServiceConfig) {
cfg.service(web::resource("").route(web::post().to(SeqHandler(swap_indexes)))); cfg.service(web::resource("").route(web::post().to(SeqHandler(swap_indexes))));
} }
#[derive(DeserializeFromValue, Debug, Clone, PartialEq, Eq)] #[derive(Deserr, Debug, Clone, PartialEq, Eq)]
#[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)] #[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)]
pub struct SwapIndexesPayload { pub struct SwapIndexesPayload {
#[deserr(error = DeserrJsonError<InvalidSwapIndexes>, missing_field_error = DeserrJsonError::missing_swap_indexes)] #[deserr(error = DeserrJsonError<InvalidSwapIndexes>, missing_field_error = DeserrJsonError::missing_swap_indexes)]

View File

@ -1,6 +1,6 @@
use actix_web::web::Data; use actix_web::web::Data;
use actix_web::{web, HttpRequest, HttpResponse}; use actix_web::{web, HttpRequest, HttpResponse};
use deserr::DeserializeFromValue; use deserr::Deserr;
use index_scheduler::{IndexScheduler, Query, TaskId}; use index_scheduler::{IndexScheduler, Query, TaskId};
use meilisearch_types::deserr::query_params::Param; use meilisearch_types::deserr::query_params::Param;
use meilisearch_types::deserr::DeserrQueryParamError; use meilisearch_types::deserr::DeserrQueryParamError;
@ -162,7 +162,7 @@ impl From<Details> for DetailsView {
} }
} }
#[derive(Debug, DeserializeFromValue)] #[derive(Debug, Deserr)]
#[deserr(error = DeserrQueryParamError, rename_all = camelCase, deny_unknown_fields)] #[deserr(error = DeserrQueryParamError, rename_all = camelCase, deny_unknown_fields)]
pub struct TasksFilterQuery { pub struct TasksFilterQuery {
#[deserr(default = Param(DEFAULT_LIMIT), error = DeserrQueryParamError<InvalidTaskLimit>)] #[deserr(default = Param(DEFAULT_LIMIT), error = DeserrQueryParamError<InvalidTaskLimit>)]
@ -181,19 +181,20 @@ pub struct TasksFilterQuery {
#[deserr(default, error = DeserrQueryParamError<InvalidIndexUid>)] #[deserr(default, error = DeserrQueryParamError<InvalidIndexUid>)]
pub index_uids: OptionStarOrList<IndexUid>, pub index_uids: OptionStarOrList<IndexUid>,
#[deserr(default, error = DeserrQueryParamError<InvalidTaskAfterEnqueuedAt>, from(OptionStarOr<String>) = deserialize_date_after -> InvalidTaskDateError)] #[deserr(default, error = DeserrQueryParamError<InvalidTaskAfterEnqueuedAt>, try_from(OptionStarOr<String>) = deserialize_date_after -> InvalidTaskDateError)]
pub after_enqueued_at: OptionStarOr<OffsetDateTime>, pub after_enqueued_at: OptionStarOr<OffsetDateTime>,
#[deserr(default, error = DeserrQueryParamError<InvalidTaskBeforeEnqueuedAt>, from(OptionStarOr<String>) = deserialize_date_before -> InvalidTaskDateError)] #[deserr(default, error = DeserrQueryParamError<InvalidTaskBeforeEnqueuedAt>, try_from(OptionStarOr<String>) = deserialize_date_before -> InvalidTaskDateError)]
pub before_enqueued_at: OptionStarOr<OffsetDateTime>, pub before_enqueued_at: OptionStarOr<OffsetDateTime>,
#[deserr(default, error = DeserrQueryParamError<InvalidTaskAfterStartedAt>, from(OptionStarOr<String>) = deserialize_date_after -> InvalidTaskDateError)] #[deserr(default, error = DeserrQueryParamError<InvalidTaskAfterStartedAt>, try_from(OptionStarOr<String>) = deserialize_date_after -> InvalidTaskDateError)]
pub after_started_at: OptionStarOr<OffsetDateTime>, pub after_started_at: OptionStarOr<OffsetDateTime>,
#[deserr(default, error = DeserrQueryParamError<InvalidTaskBeforeStartedAt>, from(OptionStarOr<String>) = deserialize_date_before -> InvalidTaskDateError)] #[deserr(default, error = DeserrQueryParamError<InvalidTaskBeforeStartedAt>, try_from(OptionStarOr<String>) = deserialize_date_before -> InvalidTaskDateError)]
pub before_started_at: OptionStarOr<OffsetDateTime>, pub before_started_at: OptionStarOr<OffsetDateTime>,
#[deserr(default, error = DeserrQueryParamError<InvalidTaskAfterFinishedAt>, from(OptionStarOr<String>) = deserialize_date_after -> InvalidTaskDateError)] #[deserr(default, error = DeserrQueryParamError<InvalidTaskAfterFinishedAt>, try_from(OptionStarOr<String>) = deserialize_date_after -> InvalidTaskDateError)]
pub after_finished_at: OptionStarOr<OffsetDateTime>, pub after_finished_at: OptionStarOr<OffsetDateTime>,
#[deserr(default, error = DeserrQueryParamError<InvalidTaskBeforeFinishedAt>, from(OptionStarOr<String>) = deserialize_date_before -> InvalidTaskDateError)] #[deserr(default, error = DeserrQueryParamError<InvalidTaskBeforeFinishedAt>, try_from(OptionStarOr<String>) = deserialize_date_before -> InvalidTaskDateError)]
pub before_finished_at: OptionStarOr<OffsetDateTime>, pub before_finished_at: OptionStarOr<OffsetDateTime>,
} }
impl TasksFilterQuery { impl TasksFilterQuery {
fn into_query(self) -> Query { fn into_query(self) -> Query {
Query { Query {
@ -235,7 +236,7 @@ impl TaskDeletionOrCancelationQuery {
} }
} }
#[derive(Debug, DeserializeFromValue)] #[derive(Debug, Deserr)]
#[deserr(error = DeserrQueryParamError, rename_all = camelCase, deny_unknown_fields)] #[deserr(error = DeserrQueryParamError, rename_all = camelCase, deny_unknown_fields)]
pub struct TaskDeletionOrCancelationQuery { pub struct TaskDeletionOrCancelationQuery {
#[deserr(default, error = DeserrQueryParamError<InvalidTaskUids>)] #[deserr(default, error = DeserrQueryParamError<InvalidTaskUids>)]
@ -249,19 +250,20 @@ pub struct TaskDeletionOrCancelationQuery {
#[deserr(default, error = DeserrQueryParamError<InvalidIndexUid>)] #[deserr(default, error = DeserrQueryParamError<InvalidIndexUid>)]
pub index_uids: OptionStarOrList<IndexUid>, pub index_uids: OptionStarOrList<IndexUid>,
#[deserr(default, error = DeserrQueryParamError<InvalidTaskAfterEnqueuedAt>, from(OptionStarOr<String>) = deserialize_date_after -> InvalidTaskDateError)] #[deserr(default, error = DeserrQueryParamError<InvalidTaskAfterEnqueuedAt>, try_from(OptionStarOr<String>) = deserialize_date_after -> InvalidTaskDateError)]
pub after_enqueued_at: OptionStarOr<OffsetDateTime>, pub after_enqueued_at: OptionStarOr<OffsetDateTime>,
#[deserr(default, error = DeserrQueryParamError<InvalidTaskBeforeEnqueuedAt>, from(OptionStarOr<String>) = deserialize_date_before -> InvalidTaskDateError)] #[deserr(default, error = DeserrQueryParamError<InvalidTaskBeforeEnqueuedAt>, try_from(OptionStarOr<String>) = deserialize_date_before -> InvalidTaskDateError)]
pub before_enqueued_at: OptionStarOr<OffsetDateTime>, pub before_enqueued_at: OptionStarOr<OffsetDateTime>,
#[deserr(default, error = DeserrQueryParamError<InvalidTaskAfterStartedAt>, from(OptionStarOr<String>) = deserialize_date_after -> InvalidTaskDateError)] #[deserr(default, error = DeserrQueryParamError<InvalidTaskAfterStartedAt>, try_from(OptionStarOr<String>) = deserialize_date_after -> InvalidTaskDateError)]
pub after_started_at: OptionStarOr<OffsetDateTime>, pub after_started_at: OptionStarOr<OffsetDateTime>,
#[deserr(default, error = DeserrQueryParamError<InvalidTaskBeforeStartedAt>, from(OptionStarOr<String>) = deserialize_date_before -> InvalidTaskDateError)] #[deserr(default, error = DeserrQueryParamError<InvalidTaskBeforeStartedAt>, try_from(OptionStarOr<String>) = deserialize_date_before -> InvalidTaskDateError)]
pub before_started_at: OptionStarOr<OffsetDateTime>, pub before_started_at: OptionStarOr<OffsetDateTime>,
#[deserr(default, error = DeserrQueryParamError<InvalidTaskAfterFinishedAt>, from(OptionStarOr<String>) = deserialize_date_after -> InvalidTaskDateError)] #[deserr(default, error = DeserrQueryParamError<InvalidTaskAfterFinishedAt>, try_from(OptionStarOr<String>) = deserialize_date_after -> InvalidTaskDateError)]
pub after_finished_at: OptionStarOr<OffsetDateTime>, pub after_finished_at: OptionStarOr<OffsetDateTime>,
#[deserr(default, error = DeserrQueryParamError<InvalidTaskBeforeFinishedAt>, from(OptionStarOr<String>) = deserialize_date_before -> InvalidTaskDateError)] #[deserr(default, error = DeserrQueryParamError<InvalidTaskBeforeFinishedAt>, try_from(OptionStarOr<String>) = deserialize_date_before -> InvalidTaskDateError)]
pub before_finished_at: OptionStarOr<OffsetDateTime>, pub before_finished_at: OptionStarOr<OffsetDateTime>,
} }
impl TaskDeletionOrCancelationQuery { impl TaskDeletionOrCancelationQuery {
fn into_query(self) -> Query { fn into_query(self) -> Query {
Query { Query {
@ -498,7 +500,7 @@ pub fn deserialize_date_before(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use deserr::DeserializeFromValue; use deserr::Deserr;
use meili_snap::snapshot; use meili_snap::snapshot;
use meilisearch_types::deserr::DeserrQueryParamError; use meilisearch_types::deserr::DeserrQueryParamError;
use meilisearch_types::error::{Code, ResponseError}; use meilisearch_types::error::{Code, ResponseError};
@ -507,7 +509,7 @@ mod tests {
fn deserr_query_params<T>(j: &str) -> Result<T, ResponseError> fn deserr_query_params<T>(j: &str) -> Result<T, ResponseError>
where where
T: DeserializeFromValue<DeserrQueryParamError>, T: Deserr<DeserrQueryParamError>,
{ {
let value = serde_urlencoded::from_str::<serde_json::Value>(j) let value = serde_urlencoded::from_str::<serde_json::Value>(j)
.map_err(|e| ResponseError::from_msg(e.to_string(), Code::BadRequest))?; .map_err(|e| ResponseError::from_msg(e.to_string(), Code::BadRequest))?;

View File

@ -3,7 +3,7 @@ use std::collections::{BTreeMap, BTreeSet, HashSet};
use std::str::FromStr; use std::str::FromStr;
use std::time::Instant; use std::time::Instant;
use deserr::DeserializeFromValue; use deserr::Deserr;
use either::Either; use either::Either;
use meilisearch_types::deserr::DeserrJsonError; use meilisearch_types::deserr::DeserrJsonError;
use meilisearch_types::error::deserr_codes::*; use meilisearch_types::error::deserr_codes::*;
@ -29,7 +29,7 @@ pub const DEFAULT_CROP_MARKER: fn() -> String = || "…".to_string();
pub const DEFAULT_HIGHLIGHT_PRE_TAG: fn() -> String = || "<em>".to_string(); pub const DEFAULT_HIGHLIGHT_PRE_TAG: fn() -> String = || "<em>".to_string();
pub const DEFAULT_HIGHLIGHT_POST_TAG: fn() -> String = || "</em>".to_string(); pub const DEFAULT_HIGHLIGHT_POST_TAG: fn() -> String = || "</em>".to_string();
#[derive(Debug, Clone, Default, PartialEq, Eq, DeserializeFromValue)] #[derive(Debug, Clone, Default, PartialEq, Eq, Deserr)]
#[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)] #[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)]
pub struct SearchQuery { pub struct SearchQuery {
#[deserr(default, error = DeserrJsonError<InvalidSearchQ>)] #[deserr(default, error = DeserrJsonError<InvalidSearchQ>)]
@ -74,7 +74,7 @@ impl SearchQuery {
} }
} }
#[derive(Debug, Clone, PartialEq, Eq, DeserializeFromValue)] #[derive(Debug, Clone, PartialEq, Eq, Deserr)]
#[deserr(rename_all = camelCase)] #[deserr(rename_all = camelCase)]
pub enum MatchingStrategy { pub enum MatchingStrategy {
/// Remove query words from last to first /// Remove query words from last to first

View File

@ -12,7 +12,7 @@ byteorder = "1.4.3"
charabia = { version = "0.7.0", default-features = false } charabia = { version = "0.7.0", default-features = false }
concat-arrays = "0.1.2" concat-arrays = "0.1.2"
crossbeam-channel = "0.5.6" crossbeam-channel = "0.5.6"
deserr = "0.3.0" deserr = "0.4.0"
either = "1.8.0" either = "1.8.0"
flatten-serde-json = { path = "../flatten-serde-json" } flatten-serde-json = { path = "../flatten-serde-json" }
fst = "0.4.7" fst = "0.4.7"

View File

@ -2,7 +2,7 @@ use std::collections::{BTreeSet, HashMap, HashSet};
use std::result::Result as StdResult; use std::result::Result as StdResult;
use charabia::{Tokenizer, TokenizerBuilder}; use charabia::{Tokenizer, TokenizerBuilder};
use deserr::{DeserializeError, DeserializeFromValue}; use deserr::{DeserializeError, Deserr};
use itertools::Itertools; use itertools::Itertools;
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
use time::OffsetDateTime; use time::OffsetDateTime;
@ -23,9 +23,9 @@ pub enum Setting<T> {
NotSet, NotSet,
} }
impl<T, E> DeserializeFromValue<E> for Setting<T> impl<T, E> Deserr<E> for Setting<T>
where where
T: DeserializeFromValue<E>, T: Deserr<E>,
E: DeserializeError, E: DeserializeError,
{ {
fn deserialize_from_value<V: deserr::IntoValue>( fn deserialize_from_value<V: deserr::IntoValue>(