diff --git a/dump/src/reader/compat/mod.rs b/dump/src/reader/compat/mod.rs index 42767f12a..ab9857c45 100644 --- a/dump/src/reader/compat/mod.rs +++ b/dump/src/reader/compat/mod.rs @@ -148,17 +148,3 @@ impl From for CompatIndex { CompatIndex::Compat(value) } } - -/// Parses the v1 version of the Asc ranking rules `asc(price)`and returns the field name. -pub fn asc_ranking_rule(text: &str) -> Option<&str> { - text.split_once("asc(") - .and_then(|(_, tail)| tail.rsplit_once(')')) - .map(|(field, _)| field) -} - -/// Parses the v1 version of the Desc ranking rules `desc(price)`and returns the field name. -pub fn desc_ranking_rule(text: &str) -> Option<&str> { - text.split_once("desc(") - .and_then(|(_, tail)| tail.rsplit_once(')')) - .map(|(field, _)| field) -} diff --git a/dump/src/reader/compat/v2_to_v3.rs b/dump/src/reader/compat/v2_to_v3.rs index 9bcc17649..7579811d0 100644 --- a/dump/src/reader/compat/v2_to_v3.rs +++ b/dump/src/reader/compat/v2_to_v3.rs @@ -4,7 +4,7 @@ use std::str::FromStr; use time::OffsetDateTime; use uuid::Uuid; -use crate::reader::{v2, v3, DumpReader, IndexReader}; +use crate::reader::{v2, v3}; use crate::Result; use super::v3_to_v4::CompatV3ToV4; @@ -19,7 +19,8 @@ impl CompatV2ToV3 { } pub fn index_uuid(&self) -> Vec { - self.index_uuid() + self.from + .index_uuid() .into_iter() .map(|index| v3::meta::IndexUuid { uid: index.uid, @@ -54,7 +55,7 @@ impl CompatV2ToV3 { pub fn tasks( &mut self, ) -> Box)>> + '_> { - let indexes = self.from.index_uuid.clone(); + let _indexes = self.from.index_uuid.clone(); Box::new( self.from @@ -241,7 +242,7 @@ pub fn update_from_unchecked_update_meta(update: v2::updates::UpdateMeta) -> v3: match update { v2::updates::UpdateMeta::DocumentsAddition { method, - format, + format: _, primary_key, } => v3::updates::Update::DocumentAddition { primary_key, diff --git a/dump/src/reader/compat/v3_to_v4.rs b/dump/src/reader/compat/v3_to_v4.rs index 068f2f41d..98709a0fb 100644 --- a/dump/src/reader/compat/v3_to_v4.rs +++ b/dump/src/reader/compat/v3_to_v4.rs @@ -1,4 +1,4 @@ -use crate::reader::{v3, v4, DumpReader, IndexReader}; +use crate::reader::{v3, v4}; use crate::Result; use super::v2_to_v3::{CompatIndexV2ToV3, CompatV2ToV3}; diff --git a/dump/src/reader/compat/v4_to_v5.rs b/dump/src/reader/compat/v4_to_v5.rs index b6bae8880..59579a51d 100644 --- a/dump/src/reader/compat/v4_to_v5.rs +++ b/dump/src/reader/compat/v4_to_v5.rs @@ -1,4 +1,4 @@ -use crate::reader::{v4, v5, DumpReader, IndexReader}; +use crate::reader::{v4, v5}; use crate::Result; use super::v3_to_v4::{CompatIndexV3ToV4, CompatV3ToV4}; diff --git a/dump/src/reader/compat/v5_to_v6.rs b/dump/src/reader/compat/v5_to_v6.rs index c47ef788f..a0fc0aa50 100644 --- a/dump/src/reader/compat/v5_to_v6.rs +++ b/dump/src/reader/compat/v5_to_v6.rs @@ -1,4 +1,4 @@ -use crate::reader::{v5, v6, DumpReader, IndexReader}; +use crate::reader::{v5, v6}; use crate::Result; use super::v4_to_v5::{CompatIndexV4ToV5, CompatV4ToV5}; diff --git a/dump/src/reader/v2/mod.rs b/dump/src/reader/v2/mod.rs index a69ebd828..f9baee09e 100644 --- a/dump/src/reader/v2/mod.rs +++ b/dump/src/reader/v2/mod.rs @@ -41,7 +41,7 @@ use crate::{IndexMetadata, Result, Version}; use self::meta::{DumpMeta, IndexUuid}; -use super::{compat::v2_to_v3::CompatV2ToV3, IndexReader}; +use super::compat::v2_to_v3::CompatV2ToV3; pub type Document = serde_json::Map; pub type Settings = settings::Settings; @@ -51,15 +51,8 @@ pub type Unchecked = settings::Unchecked; pub type Task = updates::UpdateEntry; pub type UpdateFile = File; -// ===== Other types to clarify the code of the compat module -// everything related to the tasks -pub type Status = updates::UpdateStatus; -// pub type Kind = updates::Update; -pub type Details = updates::UpdateResult; - // everything related to the errors pub type ResponseError = errors::ResponseError; -// pub type Code = errors::Code; #[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "camelCase")] diff --git a/dump/src/reader/v3/errors.rs b/dump/src/reader/v3/errors.rs index 6d236c187..40c4d2c8d 100644 --- a/dump/src/reader/v3/errors.rs +++ b/dump/src/reader/v3/errors.rs @@ -1,51 +1,5 @@ -use std::fmt; - -use http::StatusCode; use serde::{Deserialize, Serialize}; -pub trait ErrorCode: std::error::Error { - fn error_code(&self) -> Code; - - /// returns the HTTP status code ascociated with the error - fn http_status(&self) -> StatusCode { - self.error_code().http() - } - - /// returns the doc url ascociated with the error - fn error_url(&self) -> String { - self.error_code().url() - } - - /// returns error name, used as error code - fn error_name(&self) -> String { - self.error_code().name() - } - - /// return the error type - fn error_type(&self) -> String { - self.error_code().type_() - } -} - -#[allow(clippy::enum_variant_names)] -enum ErrorType { - InternalError, - InvalidRequestError, - AuthenticationError, -} - -impl fmt::Display for ErrorType { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use ErrorType::*; - - match self { - InternalError => write!(f, "internal"), - InvalidRequestError => write!(f, "invalid_request"), - AuthenticationError => write!(f, "auth"), - } - } -} - #[derive(Serialize, Deserialize, Debug, Clone, Copy)] pub enum Code { // index related error @@ -95,152 +49,3 @@ pub enum Code { MalformedDump, UnretrievableErrorCode, } - -impl Code { - /// ascociate a `Code` variant to the actual ErrCode - fn err_code(&self) -> ErrCode { - use Code::*; - - match self { - // index related errors - // create index is thrown on internal error while creating an index. - CreateIndex => { - ErrCode::internal("index_creation_failed", StatusCode::INTERNAL_SERVER_ERROR) - } - IndexAlreadyExists => ErrCode::invalid("index_already_exists", StatusCode::CONFLICT), - // thrown when requesting an unexisting index - IndexNotFound => ErrCode::invalid("index_not_found", StatusCode::NOT_FOUND), - InvalidIndexUid => ErrCode::invalid("invalid_index_uid", StatusCode::BAD_REQUEST), - - // invalid state error - InvalidState => ErrCode::internal("invalid_state", StatusCode::INTERNAL_SERVER_ERROR), - // thrown when no primary key has been set - MissingPrimaryKey => { - ErrCode::invalid("primary_key_inference_failed", StatusCode::BAD_REQUEST) - } - // error thrown when trying to set an already existing primary key - PrimaryKeyAlreadyPresent => { - ErrCode::invalid("index_primary_key_already_exists", StatusCode::BAD_REQUEST) - } - // invalid ranking rule - InvalidRankingRule => ErrCode::invalid("invalid_ranking_rule", StatusCode::BAD_REQUEST), - - // invalid database - InvalidStore => { - ErrCode::internal("invalid_store_file", StatusCode::INTERNAL_SERVER_ERROR) - } - - // invalid document - MaxFieldsLimitExceeded => { - ErrCode::invalid("max_fields_limit_exceeded", StatusCode::BAD_REQUEST) - } - MissingDocumentId => ErrCode::invalid("missing_document_id", StatusCode::BAD_REQUEST), - InvalidDocumentId => ErrCode::invalid("invalid_document_id", StatusCode::BAD_REQUEST), - - // error related to filters - Filter => ErrCode::invalid("invalid_filter", StatusCode::BAD_REQUEST), - // error related to sorts - Sort => ErrCode::invalid("invalid_sort", StatusCode::BAD_REQUEST), - - BadParameter => ErrCode::invalid("bad_parameter", StatusCode::BAD_REQUEST), - BadRequest => ErrCode::invalid("bad_request", StatusCode::BAD_REQUEST), - DatabaseSizeLimitReached => ErrCode::internal( - "database_size_limit_reached", - StatusCode::INTERNAL_SERVER_ERROR, - ), - DocumentNotFound => ErrCode::invalid("document_not_found", StatusCode::NOT_FOUND), - Internal => ErrCode::internal("internal", StatusCode::INTERNAL_SERVER_ERROR), - InvalidGeoField => ErrCode::invalid("invalid_geo_field", StatusCode::BAD_REQUEST), - InvalidToken => ErrCode::authentication("invalid_api_key", StatusCode::FORBIDDEN), - MissingAuthorizationHeader => { - ErrCode::authentication("missing_authorization_header", StatusCode::UNAUTHORIZED) - } - TaskNotFound => ErrCode::invalid("task_not_found", StatusCode::NOT_FOUND), - DumpNotFound => ErrCode::invalid("dump_not_found", StatusCode::NOT_FOUND), - NoSpaceLeftOnDevice => { - ErrCode::internal("no_space_left_on_device", StatusCode::INTERNAL_SERVER_ERROR) - } - PayloadTooLarge => ErrCode::invalid("payload_too_large", StatusCode::PAYLOAD_TOO_LARGE), - RetrieveDocument => { - ErrCode::internal("unretrievable_document", StatusCode::BAD_REQUEST) - } - SearchDocuments => ErrCode::internal("search_error", StatusCode::BAD_REQUEST), - UnsupportedMediaType => { - ErrCode::invalid("unsupported_media_type", StatusCode::UNSUPPORTED_MEDIA_TYPE) - } - - // error related to dump - DumpAlreadyInProgress => { - ErrCode::invalid("dump_already_processing", StatusCode::CONFLICT) - } - DumpProcessFailed => { - ErrCode::internal("dump_process_failed", StatusCode::INTERNAL_SERVER_ERROR) - } - MissingContentType => { - ErrCode::invalid("missing_content_type", StatusCode::UNSUPPORTED_MEDIA_TYPE) - } - MalformedPayload => ErrCode::invalid("malformed_payload", StatusCode::BAD_REQUEST), - InvalidContentType => { - ErrCode::invalid("invalid_content_type", StatusCode::UNSUPPORTED_MEDIA_TYPE) - } - MissingPayload => ErrCode::invalid("missing_payload", StatusCode::BAD_REQUEST), - UnretrievableErrorCode => { - ErrCode::invalid("unretrievable_error_code", StatusCode::BAD_REQUEST) - } - MalformedDump => ErrCode::invalid("malformed_dump", StatusCode::BAD_REQUEST), - } - } - - /// return the HTTP status code ascociated with the `Code` - fn http(&self) -> StatusCode { - self.err_code().status_code - } - - /// return error name, used as error code - fn name(&self) -> String { - self.err_code().error_name.to_string() - } - - /// return the error type - fn type_(&self) -> String { - self.err_code().error_type.to_string() - } - - /// return the doc url ascociated with the error - fn url(&self) -> String { - format!("https://docs.meilisearch.com/errors#{}", self.name()) - } -} - -/// Internal structure providing a convenient way to create error codes -struct ErrCode { - status_code: StatusCode, - error_type: ErrorType, - error_name: &'static str, -} - -impl ErrCode { - fn authentication(error_name: &'static str, status_code: StatusCode) -> ErrCode { - ErrCode { - status_code, - error_name, - error_type: ErrorType::AuthenticationError, - } - } - - fn internal(error_name: &'static str, status_code: StatusCode) -> ErrCode { - ErrCode { - status_code, - error_name, - error_type: ErrorType::InternalError, - } - } - - fn invalid(error_name: &'static str, status_code: StatusCode) -> ErrCode { - ErrCode { - status_code, - error_name, - error_type: ErrorType::InvalidRequestError, - } - } -} diff --git a/dump/src/reader/v3/mod.rs b/dump/src/reader/v3/mod.rs index 77cf8085b..642062a73 100644 --- a/dump/src/reader/v3/mod.rs +++ b/dump/src/reader/v3/mod.rs @@ -41,7 +41,7 @@ use crate::{IndexMetadata, Result, Version}; use self::meta::{DumpMeta, IndexUuid}; -use super::{compat::v3_to_v4::CompatV3ToV4, IndexReader}; +use super::compat::v3_to_v4::CompatV3ToV4; pub type Document = serde_json::Map; pub type Settings = settings::Settings; @@ -55,13 +55,11 @@ pub type UpdateFile = File; // everything related to the tasks pub type Status = updates::UpdateStatus; pub type Kind = updates::Update; -pub type Details = updates::UpdateResult; // everything related to the settings pub type Setting = settings::Setting; // everything related to the errors -// pub type ResponseError = errors::ResponseError; pub type Code = errors::Code; #[derive(Serialize, Deserialize, Debug)] diff --git a/dump/src/reader/v4/mod.rs b/dump/src/reader/v4/mod.rs index 1f2ab9649..d2d775ad5 100644 --- a/dump/src/reader/v4/mod.rs +++ b/dump/src/reader/v4/mod.rs @@ -19,7 +19,7 @@ use crate::{IndexMetadata, Result, Version}; use self::meta::{DumpMeta, IndexUuid}; -use super::{compat::v4_to_v5::CompatV4ToV5, DumpReader, IndexReader}; +use super::compat::v4_to_v5::CompatV4ToV5; pub type Document = serde_json::Map; pub type Settings = settings::Settings; @@ -30,21 +30,11 @@ pub type Task = tasks::Task; pub type UpdateFile = File; pub type Key = keys::Key; -// ===== Other types to clarify the code of the compat module -// everything related to the tasks -pub type Status = tasks::TaskStatus; -pub type Kind = tasks::TaskType; -pub type Details = tasks::TaskDetails; - // everything related to the settings pub type Setting = settings::Setting; -pub type TypoTolerance = settings::TypoSettings; -pub type MinWordSizeForTypos = settings::MinWordSizeTyposSetting; // everything related to the api keys pub type Action = keys::Action; -pub type StarOr = meta::StarOr; -pub type IndexUid = meta::IndexUid; // everything related to the errors pub type ResponseError = errors::ResponseError; diff --git a/dump/src/reader/v4/tasks.rs b/dump/src/reader/v4/tasks.rs index dbe4d225e..dfe5452d8 100644 --- a/dump/src/reader/v4/tasks.rs +++ b/dump/src/reader/v4/tasks.rs @@ -1,7 +1,5 @@ -use std::fmt::Write; - -use serde::{Deserialize, Serializer}; -use time::{Duration, OffsetDateTime}; +use serde::Deserialize; +use time::OffsetDateTime; use uuid::Uuid; use super::{ @@ -49,56 +47,6 @@ pub enum TaskContent { }, } -#[derive(Debug)] -#[cfg_attr(test, derive(serde::Serialize))] -#[cfg_attr(test, serde(untagged))] -#[allow(clippy::large_enum_variant)] -pub enum TaskDetails { - #[cfg_attr(test, serde(rename_all = "camelCase"))] - DocumentAddition { - received_documents: usize, - indexed_documents: Option, - }, - #[cfg_attr(test, serde(rename_all = "camelCase"))] - Settings { - #[cfg_attr(test, serde(flatten))] - settings: Settings, - }, - #[cfg_attr(test, serde(rename_all = "camelCase"))] - IndexInfo { primary_key: Option }, - #[cfg_attr(test, serde(rename_all = "camelCase"))] - DocumentDeletion { - received_document_ids: usize, - deleted_documents: Option, - }, - #[cfg_attr(test, serde(rename_all = "camelCase"))] - ClearAll { deleted_documents: Option }, -} - -#[derive(Debug)] -#[cfg_attr(test, derive(serde::Serialize))] -#[cfg_attr(test, serde(rename_all = "camelCase"))] -pub enum TaskStatus { - Enqueued, - Processing, - Succeeded, - Failed, -} - -#[derive(Debug)] -#[cfg_attr(test, derive(serde::Serialize))] -#[cfg_attr(test, serde(rename_all = "camelCase"))] -pub enum TaskType { - IndexCreation, - IndexUpdate, - IndexDeletion, - DocumentAddition, - DocumentPartial, - DocumentDeletion, - SettingsUpdate, - ClearAll, -} - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize)] #[cfg_attr(test, derive(serde::Serialize))] pub enum IndexDocumentsMethod { @@ -189,214 +137,17 @@ impl std::ops::Deref for IndexUid { } } -#[derive(Debug)] -#[cfg_attr(test, derive(serde::Serialize))] -#[cfg_attr(test, serde(rename_all = "camelCase"))] -pub struct TaskView { - uid: TaskId, - index_uid: String, - status: TaskStatus, - #[cfg_attr(test, serde(rename = "type"))] - task_type: TaskType, - #[cfg_attr(test, serde(skip_serializing_if = "Option::is_none"))] - details: Option, - #[cfg_attr(test, serde(skip_serializing_if = "Option::is_none"))] - error: Option, - #[cfg_attr(test, serde(serialize_with = "serialize_duration"))] - duration: Option, - #[cfg_attr(test, serde(serialize_with = "time::serde::rfc3339::serialize"))] - enqueued_at: OffsetDateTime, - #[cfg_attr( - test, - serde(serialize_with = "time::serde::rfc3339::option::serialize") - )] - started_at: Option, - #[cfg_attr( - test, - serde(serialize_with = "time::serde::rfc3339::option::serialize") - )] - finished_at: Option, - #[cfg_attr(test, serde(skip_serializing_if = "Option::is_none"))] - batch_uid: Option>, -} - -impl From for TaskView { - fn from(task: Task) -> Self { - let Task { - id, - index_uid, - content, - events, - } = task; - - let (task_type, mut details) = match content { - TaskContent::DocumentAddition { - merge_strategy, - documents_count, - .. - } => { - let details = TaskDetails::DocumentAddition { - received_documents: documents_count, - indexed_documents: None, - }; - - let task_type = match merge_strategy { - IndexDocumentsMethod::UpdateDocuments => TaskType::DocumentPartial, - IndexDocumentsMethod::ReplaceDocuments => TaskType::DocumentAddition, - _ => unreachable!("Unexpected document merge strategy."), - }; - - (task_type, Some(details)) - } - TaskContent::DocumentDeletion(DocumentDeletion::Ids(ids)) => ( - TaskType::DocumentDeletion, - Some(TaskDetails::DocumentDeletion { - received_document_ids: ids.len(), - deleted_documents: None, - }), - ), - TaskContent::DocumentDeletion(DocumentDeletion::Clear) => ( - TaskType::ClearAll, - Some(TaskDetails::ClearAll { - deleted_documents: None, - }), - ), - TaskContent::IndexDeletion => ( - TaskType::IndexDeletion, - Some(TaskDetails::ClearAll { - deleted_documents: None, - }), - ), - TaskContent::SettingsUpdate { settings, .. } => ( - TaskType::SettingsUpdate, - Some(TaskDetails::Settings { settings }), - ), - TaskContent::IndexCreation { primary_key } => ( - TaskType::IndexCreation, - Some(TaskDetails::IndexInfo { primary_key }), - ), - TaskContent::IndexUpdate { primary_key } => ( - TaskType::IndexUpdate, - Some(TaskDetails::IndexInfo { primary_key }), - ), - }; - - // An event always has at least one event: "Created" - let (status, error, finished_at) = match events.last().unwrap() { - TaskEvent::Created(_) => (TaskStatus::Enqueued, None, None), - TaskEvent::Batched { .. } => (TaskStatus::Enqueued, None, None), - TaskEvent::Processing(_) => (TaskStatus::Processing, None, None), - TaskEvent::Succeded { timestamp, result } => { - match (result, &mut details) { - ( - TaskResult::DocumentAddition { - indexed_documents: num, - .. - }, - Some(TaskDetails::DocumentAddition { - ref mut indexed_documents, - .. - }), - ) => { - indexed_documents.replace(*num); - } - ( - TaskResult::DocumentDeletion { - deleted_documents: docs, - .. - }, - Some(TaskDetails::DocumentDeletion { - ref mut deleted_documents, - .. - }), - ) => { - deleted_documents.replace(*docs); - } - ( - TaskResult::ClearAll { - deleted_documents: docs, - }, - Some(TaskDetails::ClearAll { - ref mut deleted_documents, - }), - ) => { - deleted_documents.replace(*docs); - } - _ => (), - } - (TaskStatus::Succeeded, None, Some(*timestamp)) - } - TaskEvent::Failed { timestamp, error } => { - match details { - Some(TaskDetails::DocumentDeletion { - ref mut deleted_documents, - .. - }) => { - deleted_documents.replace(0); - } - Some(TaskDetails::ClearAll { - ref mut deleted_documents, - .. - }) => { - deleted_documents.replace(0); - } - Some(TaskDetails::DocumentAddition { - ref mut indexed_documents, - .. - }) => { - indexed_documents.replace(0); - } - _ => (), - } - (TaskStatus::Failed, Some(error.clone()), Some(*timestamp)) - } - }; - - let enqueued_at = match events.first() { - Some(TaskEvent::Created(ts)) => *ts, - _ => unreachable!("A task must always have a creation event."), - }; - - let started_at = events.iter().find_map(|e| match e { - TaskEvent::Processing(ts) => Some(*ts), - _ => None, - }); - - let duration = finished_at.zip(started_at).map(|(tf, ts)| (tf - ts)); - - let batch_uid = if true { - let id = events.iter().find_map(|e| match e { - TaskEvent::Batched { batch_id, .. } => Some(*batch_id), - _ => None, - }); - Some(id) - } else { - None - }; - - Self { - uid: id, - index_uid: index_uid.into_inner(), - status, - task_type, - details, - error, - duration, - enqueued_at, - started_at, - finished_at, - batch_uid, - } - } -} - /// Serialize a `time::Duration` as a best effort ISO 8601 while waiting for /// https://github.com/time-rs/time/issues/378. /// This code is a port of the old code of time that was removed in 0.2. -fn serialize_duration( - duration: &Option, +#[cfg(test)] +fn serialize_duration( + duration: &Option, serializer: S, ) -> Result { + use std::fmt::Write; + use time::Duration; + match duration { Some(duration) => { // technically speaking, negative duration is not valid ISO 8601 diff --git a/dump/src/reader/v5/mod.rs b/dump/src/reader/v5/mod.rs index b95736070..27a36f66f 100644 --- a/dump/src/reader/v5/mod.rs +++ b/dump/src/reader/v5/mod.rs @@ -45,7 +45,7 @@ use uuid::Uuid; use crate::{IndexMetadata, Result, Version}; -use super::{compat::v5_to_v6::CompatV5ToV6, DumpReader, IndexReader}; +use super::compat::v5_to_v6::CompatV5ToV6; pub mod errors; pub mod keys; @@ -65,20 +65,16 @@ pub type Key = keys::Key; // ===== Other types to clarify the code of the compat module // everything related to the tasks pub type Status = tasks::TaskStatus; -pub type Kind = tasks::TaskType; pub type Details = tasks::TaskDetails; // everything related to the settings pub type Setting = settings::Setting; pub type TypoTolerance = settings::TypoSettings; pub type MinWordSizeForTypos = settings::MinWordSizeTyposSetting; -pub type FacetingSettings = settings::FacetingSettings; -pub type PaginationSettings = settings::PaginationSettings; // everything related to the api keys pub type Action = keys::Action; pub type StarOr = meta::StarOr; -pub type IndexUid = meta::IndexUid; // everything related to the errors pub type ResponseError = errors::ResponseError; diff --git a/dump/src/reader/v5/settings.rs b/dump/src/reader/v5/settings.rs index 68fae2b26..05d100cd0 100644 --- a/dump/src/reader/v5/settings.rs +++ b/dump/src/reader/v5/settings.rs @@ -3,7 +3,7 @@ use std::{ marker::PhantomData, }; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use serde::{Deserialize, Deserializer, Serialize}; #[derive(Clone, Default, Debug, Serialize, PartialEq, Eq)] pub struct Checked; @@ -49,22 +49,6 @@ pub struct Settings { pub _kind: PhantomData, } -fn serialize_with_wildcard( - field: &Setting>, - s: S, -) -> std::result::Result -where - S: Serializer, -{ - let wildcard = vec!["*".to_string()]; - match field { - Setting::Set(value) => Some(value), - Setting::Reset => Some(&wildcard), - Setting::NotSet => None, - } - .serialize(s) -} - #[derive(Debug, Clone, PartialEq, Copy)] #[cfg_attr(test, derive(serde::Serialize))] pub enum Setting { diff --git a/dump/src/reader/v5/tasks.rs b/dump/src/reader/v5/tasks.rs index 835fbab5e..73b4048af 100644 --- a/dump/src/reader/v5/tasks.rs +++ b/dump/src/reader/v5/tasks.rs @@ -1,6 +1,4 @@ -use std::fmt::Write; - -use serde::{Deserialize, Serializer}; +use serde::Deserialize; use time::{Duration, OffsetDateTime}; use uuid::Uuid; @@ -427,10 +425,13 @@ pub enum TaskDetails { /// Serialize a `time::Duration` as a best effort ISO 8601 while waiting for /// https://github.com/time-rs/time/issues/378. /// This code is a port of the old code of time that was removed in 0.2. -fn serialize_duration( +#[cfg(test)] +fn serialize_duration( duration: &Option, serializer: S, ) -> Result { + use std::fmt::Write; + match duration { Some(duration) => { // technically speaking, negative duration is not valid ISO 8601 diff --git a/dump/tests/assets/v2.dump b/dump/tests/assets/v2.dump new file mode 100644 index 000000000..eacea80a5 Binary files /dev/null and b/dump/tests/assets/v2.dump differ