From af9f5d8f24f04ad83181700e4d2933b0638fedb9 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Thu, 24 Aug 2023 15:17:54 +0300 Subject: [PATCH] add manual impl Serialize for Question --- lib/src/questions.rs | 65 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/lib/src/questions.rs b/lib/src/questions.rs index de96d11..812f440 100644 --- a/lib/src/questions.rs +++ b/lib/src/questions.rs @@ -75,7 +75,7 @@ pub struct BatchInfo { pub rating: String, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Default, Clone, Deserialize, PartialEq)] pub struct Question { #[serde(default, skip_serializing_if = "u32_is_zero")] pub num: u32, @@ -114,10 +114,6 @@ pub struct Question { pub batch_info: BatchInfo, } -fn u32_is_zero(num: &u32) -> bool { - *num == 0 -} - impl BatchInfo { pub fn is_default(&self) -> bool { *self == BatchInfo::default() @@ -150,7 +146,7 @@ impl serde::Serialize for BatchInfo { { let is_human_readable = serializer.is_human_readable(); let mut flags: BatchFlags = Default::default(); - let mut len = 1; + let mut len = 1; // (+flags) count_string_fields!((self, flags, len, BatchFlags) <- { filename: FILENAME, description: DESCRIPTION, author: AUTHOR, comment: COMMENT, url: URL, date: DATE, @@ -174,6 +170,63 @@ impl serde::Serialize for BatchInfo { } } +impl serde::Serialize for Question { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let is_human_readable = serializer.is_human_readable(); + let mut flags: QuestionFlags = Default::default(); + let mut len = 6; //(_flags + id + description + answer + num + batch_info) + + if self.num != 0 { + flags |= QuestionFlags::NUM; + } + + if !self.batch_info.is_default() { + flags |= QuestionFlags::BATCH_INFO; + } + + count_string_fields!((self, flags, len, QuestionFlags) <- { + author: AUTHOR, comment: COMMENT, comment1: COMMENT1, tour: TOUR, url: URL, date: DATE, + processed_by: PROCESSED_BY, redacted_by: REDACTED_BY, copyright: COPYRIGHT, theme: THEME, + kind: KIND, source: SOURCE, rating: RATING + }); + + let mut state = serializer.serialize_struct("Question", len)?; + + if is_human_readable { + state.skip_field("_flags")?; + } else { + state.serialize_field("_flags", &flags.bits())?; + } + + if flags.intersects(QuestionFlags::NUM) { + state.serialize_field("num", &self.num)?; + } else { + state.skip_field("num")?; + } + + state.serialize_field("id", &self.id)?; + state.serialize_field("description", &self.description)?; + state.serialize_field("answer", &self.answer)?; + + serialize_fields!((self, flags, state, QuestionFlags) <- { + author: AUTHOR, comment: COMMENT, comment1: COMMENT1, tour: TOUR, url: URL, date: DATE, + processed_by: PROCESSED_BY, redacted_by: REDACTED_BY, copyright: COPYRIGHT, theme: THEME, + kind: KIND, source: SOURCE, rating: RATING, batch_info: BATCH_INFO + }); + + if flags.intersects(QuestionFlags::BATCH_INFO) { + state.serialize_field("batch_info", &self.batch_info)?; + } else { + state.skip_field("batch_info")?; + } + + state.end() + } +} + #[cfg(any(feature = "convert", feature = "convert_async"))] pub mod convert_common { use super::{BatchInfo, Question};