From 0c0a4e31baa7090d2f96e5d913a552f2870ff17b Mon Sep 17 00:00:00 2001
From: Dmitry <b4tm4n@mail.ru>
Date: Sat, 5 Aug 2023 23:26:45 +0300
Subject: [PATCH] optional feature for source

---
 app/Cargo.toml       |   2 +-
 lib/Cargo.toml       |   3 +-
 lib/src/lib.rs       |   1 +
 lib/src/questions.rs | 106 +++++++++++++++++++++++--------------------
 4 files changed, 61 insertions(+), 51 deletions(-)

diff --git a/app/Cargo.toml b/app/Cargo.toml
index a1d9a4f..98cb0e5 100644
--- a/app/Cargo.toml
+++ b/app/Cargo.toml
@@ -14,7 +14,7 @@ name = "db_bench"
 harness = false
 
 [dependencies]
-chgk_ledb_lib = {path = "../lib", features = ["sync"]}
+chgk_ledb_lib = {path = "../lib", features = ["sync", "source"]}
 serde_json="1.0"
 zip="0.6"
 rand="0.8"
diff --git a/lib/Cargo.toml b/lib/Cargo.toml
index f262c1b..19b37c8 100644
--- a/lib/Cargo.toml
+++ b/lib/Cargo.toml
@@ -13,13 +13,14 @@ description = "Библиотека для доступа к файлу базы
 default = ["async"]
 sync = ["zstd", "memmap"]
 async = ["futures", "futures-core", "futures-util", "fmmap", "tokio", "async-compression", "async-stream"]
+source = ["zip"]
 
 [dependencies]
 serde="1.0"
 serde_derive="1.0"
 serde_json="1.0"
 bincode = "^2.0.0-rc.2"
-zip="0.6"
+zip= {version = "0.6", optional = true}
 fmmap = { version = "0.3", features = ["tokio-async"] , optional = true}
 tokio = { version = "1", features = ["fs","io-util","rt", "macros"] , optional = true}
 futures-core  = {version = "0.3", optional = true}
diff --git a/lib/src/lib.rs b/lib/src/lib.rs
index 5987921..66c5004 100644
--- a/lib/src/lib.rs
+++ b/lib/src/lib.rs
@@ -3,4 +3,5 @@ pub mod async_db;
 #[cfg(feature = "sync")]
 pub mod db;
 pub mod questions;
+#[cfg(feature = "source")]
 pub mod source;
diff --git a/lib/src/questions.rs b/lib/src/questions.rs
index 48b3489..b306f0a 100644
--- a/lib/src/questions.rs
+++ b/lib/src/questions.rs
@@ -1,7 +1,5 @@
 use serde_derive::{Deserialize, Serialize};
 
-use crate::source::{SourceQuestion, SourceQuestionsBatch};
-
 macro_rules! make {
     ($Target:ident; by {$($field:ident),+}; from $src:expr) => {$Target {$(
         $field: $src.$field
@@ -80,57 +78,67 @@ pub struct Question {
     pub batch_info: BatchInfo,
 }
 
-impl From<SourceQuestion> for Question {
-    fn from(src: SourceQuestion) -> Self {
-        make! {Self; with defaults and by {
-            num, id, description, answer, author, comment, comment1, tour, url,
-            date, processed_by, redacted_by, copyright, theme, kind, source, rating
-        }; from src}
+#[cfg(feature = "source")]
+pub mod convert {
+    use crate::source::{SourceQuestion, SourceQuestionsBatch};
+
+    use super::{BatchInfo, Question};
+
+    impl From<SourceQuestion> for Question {
+        fn from(src: SourceQuestion) -> Self {
+            make! {Self; with defaults and by {
+                num, id, description, answer, author, comment, comment1, tour, url,
+                date, processed_by, redacted_by, copyright, theme, kind, source, rating
+            }; from src}
+        }
     }
-}
 
-impl From<SourceQuestionsBatch> for BatchInfo {
-    fn from(src: SourceQuestionsBatch) -> Self {
-        make! {Self; by {
-            filename, description, author, comment, url, date,
-            processed_by, redacted_by, copyright, theme, kind, source, rating
-        }; from src}
+    impl From<SourceQuestionsBatch> for BatchInfo {
+        fn from(src: SourceQuestionsBatch) -> Self {
+            make! {Self; by {
+                filename, description, author, comment, url, date,
+                processed_by, redacted_by, copyright, theme, kind, source, rating
+            }; from src}
+        }
     }
-}
 
-impl From<SourceQuestionsBatch> for Vec<Question> {
-    fn from(src: SourceQuestionsBatch) -> Self {
-        let mut result: Vec<Question> = src
-            .questions
-            .iter()
-            .map(|item| item.clone().into())
-            .collect();
-        let batch_info = BatchInfo::from(src);
-        result.iter_mut().for_each(|question| {
-            question.batch_info = batch_info.clone();
-        });
-
-        result
-    }
-}
-
-pub trait QuestionsConverter {
-    fn convert<'a>(&'a mut self) -> Box<dyn Iterator<Item = Question> + 'a>;
-}
-
-impl<T> QuestionsConverter for T
-where
-    T: Iterator<Item = (String, Result<SourceQuestionsBatch, serde_json::Error>)>,
-{
-    fn convert<'a>(&'a mut self) -> Box<dyn Iterator<Item = Question> + 'a> {
-        let iter = self
-            .filter(|(_, data)| data.is_ok())
-            .flat_map(|(filename, data)| {
-                let mut batch = data.unwrap();
-                batch.filename = filename;
-                let questions: Vec<Question> = batch.into();
-                questions
+    impl From<SourceQuestionsBatch> for Vec<Question> {
+        fn from(src: SourceQuestionsBatch) -> Self {
+            let mut result: Vec<Question> = src
+                .questions
+                .iter()
+                .map(|item| item.clone().into())
+                .collect();
+            let batch_info = BatchInfo::from(src);
+            result.iter_mut().for_each(|question| {
+                question.batch_info = batch_info.clone();
             });
-        Box::new(iter)
+
+            result
+        }
+    }
+
+    pub trait QuestionsConverter {
+        fn convert<'a>(&'a mut self) -> Box<dyn Iterator<Item = Question> + 'a>;
+    }
+
+    impl<T> QuestionsConverter for T
+    where
+        T: Iterator<Item = (String, Result<SourceQuestionsBatch, serde_json::Error>)>,
+    {
+        fn convert<'a>(&'a mut self) -> Box<dyn Iterator<Item = Question> + 'a> {
+            let iter = self
+                .filter(|(_, data)| data.is_ok())
+                .flat_map(|(filename, data)| {
+                    let mut batch = data.unwrap();
+                    batch.filename = filename;
+                    let questions: Vec<Question> = batch.into();
+                    questions
+                });
+            Box::new(iter)
+        }
     }
 }
+
+#[cfg(feature = "source")]
+pub use convert::QuestionsConverter;