Explorar el Código

tau: WIP RPC update.

parazyd hace 3 años
padre
commit
4060ad6821

+ 17 - 11
Cargo.lock

@@ -1607,7 +1607,6 @@ dependencies = [
  "rustls-pemfile",
  "semver 1.0.18",
  "serde",
- "serde_json",
  "simplelog",
  "sled",
  "sled-overlay",
@@ -1616,6 +1615,7 @@ dependencies = [
  "structopt",
  "structopt-toml",
  "thiserror",
+ "tinyjson",
  "toml 0.7.6",
  "tor-hscrypto",
  "url",
@@ -1796,7 +1796,6 @@ dependencies = [
  "easy-parallel",
  "log",
  "serde",
- "serde_json",
  "signal-hook",
  "signal-hook-async-std",
  "simplelog",
@@ -1804,6 +1803,7 @@ dependencies = [
  "smol",
  "structopt",
  "structopt-toml",
+ "tinyjson",
  "url",
 ]
 
@@ -1824,7 +1824,6 @@ dependencies = [
  "easy-parallel",
  "log",
  "serde",
- "serde_json",
  "signal-hook",
  "signal-hook-async-std",
  "simplelog",
@@ -1832,6 +1831,7 @@ dependencies = [
  "smol",
  "structopt",
  "structopt-toml",
+ "tinyjson",
  "url",
 ]
 
@@ -1855,13 +1855,13 @@ dependencies = [
  "rand 0.8.5",
  "rustls-pemfile",
  "serde",
- "serde_json",
  "signal-hook",
  "signal-hook-async-std",
  "simplelog",
  "smol",
  "structopt",
  "structopt-toml",
+ "tinyjson",
  "toml 0.7.6",
  "url",
 ]
@@ -2666,7 +2666,6 @@ dependencies = [
  "rand 0.8.5",
  "rusqlite",
  "serde",
- "serde_json",
  "signal-hook",
  "signal-hook-async-std",
  "simplelog",
@@ -2674,6 +2673,7 @@ dependencies = [
  "smol",
  "structopt",
  "structopt-toml",
+ "tinyjson",
  "url",
 ]
 
@@ -2860,13 +2860,13 @@ dependencies = [
  "libsqlite3-sys",
  "log",
  "serde",
- "serde_json",
  "signal-hook",
  "signal-hook-async-std",
  "simplelog",
  "smol",
  "structopt",
  "structopt-toml",
+ "tinyjson",
  "url",
 ]
 
@@ -3008,11 +3008,11 @@ dependencies = [
  "clap 4.3.22",
  "darkfi",
  "darkfi-serial",
+ "genevd",
  "libsqlite3-sys",
  "log",
- "serde",
- "serde_json",
  "simplelog",
+ "tinyjson",
  "url",
 ]
 
@@ -3028,13 +3028,13 @@ dependencies = [
  "libsqlite3-sys",
  "log",
  "serde",
- "serde_json",
  "signal-hook",
  "signal-hook-async-std",
  "simplelog",
  "smol",
  "structopt",
  "structopt-toml",
+ "tinyjson",
  "url",
 ]
 
@@ -3598,13 +3598,13 @@ dependencies = [
  "log",
  "semver 1.0.18",
  "serde",
- "serde_json",
  "signal-hook",
  "signal-hook-async-std",
  "simplelog",
  "smol",
  "structopt",
  "structopt-toml",
+ "tinyjson",
  "toml 0.7.6",
  "url",
 ]
@@ -5978,7 +5978,6 @@ dependencies = [
  "log",
  "rand 0.8.5",
  "serde",
- "serde_json",
  "signal-hook",
  "signal-hook-async-std",
  "simplelog",
@@ -5986,6 +5985,7 @@ dependencies = [
  "structopt",
  "structopt-toml",
  "thiserror",
+ "tinyjson",
  "toml 0.7.6",
  "url",
 ]
@@ -6135,6 +6135,12 @@ dependencies = [
  "time-core",
 ]
 
+[[package]]
+name = "tinyjson"
+version = "2.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ab95735ea2c8fd51154d01e39cf13912a78071c2d89abc49a7ef102a7dd725a"
+
 [[package]]
 name = "tinystr"
 version = "0.7.1"

+ 1 - 1
bin/tau/taud/Cargo.toml

@@ -23,8 +23,8 @@ libc = "0.2.147"
 libsqlite3-sys = {version = "0.26.0", features = ["bundled-sqlcipher-vendored-openssl"]}
 log = "0.4.20"
 rand = "0.8.5"
-serde_json = "1.0.105"
 thiserror = "1.0.47"
+tinyjson = "2.5.1"
 toml = "0.7.6"
 url = "2.4.0"
 

+ 3 - 10
bin/tau/taud/src/error.rs

@@ -16,9 +16,8 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-use serde_json::Value;
-
 use darkfi::rpc::jsonrpc::{ErrorCode, JsonError, JsonResponse, JsonResult};
+use tinyjson::JsonValue;
 
 #[derive(Debug, thiserror::Error)]
 pub enum TaudError {
@@ -31,7 +30,7 @@ pub enum TaudError {
     #[error("InternalError")]
     Darkfi(#[from] darkfi::error::Error),
     #[error("Json serialization error: `{0}`")]
-    SerdeJsonError(String),
+    JsonError(String),
     #[error("Encryption error: `{0}`")]
     EncryptionError(String),
     #[error("Decryption error: `{0}`")]
@@ -42,12 +41,6 @@ pub enum TaudError {
 
 pub type TaudResult<T> = std::result::Result<T, TaudError>;
 
-impl From<serde_json::Error> for TaudError {
-    fn from(err: serde_json::Error) -> TaudError {
-        TaudError::SerdeJsonError(err.to_string())
-    }
-}
-
 impl From<crypto_box::aead::Error> for TaudError {
     fn from(err: crypto_box::aead::Error) -> TaudError {
         TaudError::EncryptionError(err.to_string())
@@ -60,7 +53,7 @@ impl From<std::io::Error> for TaudError {
     }
 }
 
-pub fn to_json_result(res: TaudResult<Value>, id: Value) -> JsonResult {
+pub fn to_json_result(res: TaudResult<JsonValue>, id: u16) -> JsonResult {
     match res {
         Ok(v) => JsonResponse::new(v, id).into(),
         Err(err) => match err {

+ 50 - 6
bin/tau/taud/src/month_tasks.rs

@@ -17,13 +17,14 @@
  */
 
 use std::{
+    collections::HashMap,
     fs, io,
     path::{Path, PathBuf},
 };
 
 use chrono::{TimeZone, Utc};
 use log::debug;
-use serde::{Deserialize, Serialize};
+use tinyjson::JsonValue;
 
 use darkfi::util::{
     file::{load_json_file, save_json_file},
@@ -35,13 +36,54 @@ use crate::{
     task_info::TaskInfo,
 };
 
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub struct MonthTasks {
     created_at: Timestamp,
     active_tks: Vec<String>,
     deactive_tks: Vec<String>,
 }
 
+impl From<MonthTasks> for JsonValue {
+    fn from(mt: MonthTasks) -> JsonValue {
+        let active_tks: Vec<JsonValue> =
+            mt.active_tks.iter().map(|x| JsonValue::String(x.clone())).collect();
+
+        let deactive_tks: Vec<JsonValue> =
+            mt.deactive_tks.iter().map(|x| JsonValue::String(x.clone())).collect();
+
+        JsonValue::Object(HashMap::from([
+            ("created_at".to_string(), JsonValue::String(mt.created_at.0.to_string())),
+            ("active_tks".to_string(), JsonValue::Array(active_tks)),
+            ("deactive_tks".to_string(), JsonValue::Array(deactive_tks)),
+        ]))
+    }
+}
+
+impl From<JsonValue> for MonthTasks {
+    fn from(value: JsonValue) -> MonthTasks {
+        let created_at = {
+            let u64_str = value["created_at"].get::<String>().unwrap();
+            Timestamp(u64::from_str_radix(u64_str, 10).unwrap())
+        };
+
+        let active_tks: Vec<String> = value["active_tks"]
+            .get::<Vec<JsonValue>>()
+            .unwrap()
+            .iter()
+            .map(|x| x.get::<String>().unwrap().clone())
+            .collect();
+
+        let deactive_tks: Vec<String> = value["deactive_tks"]
+            .get::<Vec<JsonValue>>()
+            .unwrap()
+            .iter()
+            .map(|x| x.get::<String>().unwrap().clone())
+            .collect();
+
+        MonthTasks { created_at, active_tks, deactive_tks }
+    }
+}
+
 impl MonthTasks {
     pub fn new(active_tks: &[String], deactive_tks: &[String]) -> Self {
         Self {
@@ -98,7 +140,8 @@ impl MonthTasks {
 
     pub fn save(&self, dataset_path: &Path) -> TaudResult<()> {
         debug!(target: "tau", "MonthTasks::save()");
-        save_json_file::<Self>(&Self::get_path(&self.created_at, dataset_path), self, true)
+        let mt: JsonValue = self.clone().into();
+        save_json_file(&Self::get_path(&self.created_at, dataset_path), &mt, true)
             .map_err(TaudError::Darkfi)
     }
 
@@ -129,8 +172,8 @@ impl MonthTasks {
         // if a date is given we load that date's month tasks
         // if not, we load tasks from all months
         match date {
-            Some(date) => match load_json_file::<Self>(&Self::get_path(date, dataset_path)) {
-                Ok(mt) => Ok(mt),
+            Some(date) => match load_json_file(&Self::get_path(date, dataset_path)) {
+                Ok(mt) => Ok(mt.into()),
                 Err(_) => Self::create(date, dataset_path),
             },
             None => {
@@ -142,7 +185,8 @@ impl MonthTasks {
                 let mut loaded_mt = Self::new(&[], &[]);
 
                 for path in path_all {
-                    let mt = load_json_file::<Self>(&path)?;
+                    let mt = load_json_file(&path)?;
+                    let mt: MonthTasks = mt.into();
                     loaded_mt.created_at = mt.created_at;
                     for tks in mt.active_tks {
                         if !loaded_mt.active_tks.contains(&tks) {

+ 177 - 34
bin/tau/taud/src/task_info.rs

@@ -20,7 +20,7 @@ use std::path::{Path, PathBuf};
 
 use darkfi_serial::{SerialDecodable, SerialEncodable};
 use log::debug;
-use serde::{Deserialize, Serialize};
+use tinyjson::JsonValue;
 
 use darkfi::{
     event_graph::gen_id,
@@ -36,7 +36,7 @@ use crate::{
     util::find_free_id,
 };
 
-#[derive(Clone, Debug, Serialize, Deserialize, SerialEncodable, SerialDecodable, PartialEq, Eq)]
+#[derive(Clone, Debug, SerialEncodable, SerialDecodable, PartialEq, Eq)]
 pub struct TaskEvent {
     pub action: String,
     pub author: String,
@@ -50,13 +50,61 @@ impl TaskEvent {
     }
 }
 
-#[derive(Clone, Debug, Serialize, Deserialize, SerialDecodable, SerialEncodable, PartialEq, Eq)]
+impl From<TaskEvent> for JsonValue {
+    fn from(task_event: TaskEvent) -> JsonValue {
+        JsonValue::Object(HashMap::from([
+            ("action".to_string(), JsonValue::String(task_event.action.clone())),
+            ("author".to_string(), JsonValue::String(task_event.author.clone())),
+            ("content".to_string(), JsonValue::String(task_event.content.clone())),
+            ("timestamp".to_string(), JsonValue::String(task_event.timestamp.0.to_string())),
+        ]))
+    }
+}
+
+impl From<&JsonValue> for TaskEvent {
+    fn from(value: &JsonValue) -> TaskEvent {
+        let map = value.get::<HashMap<String, JsonValue>>().unwrap();
+        TaskEvent {
+            action: map["action"].get().unwrap().clone(),
+            author: map["author"].get().unwrap().clone(),
+            content: map["content"].get().unwrap().clone(),
+            timestamp: Timestamp(
+                u64::from_str_radix(map["timestamp"].get::<String>().unwrap(), 10).unwrap(),
+            ),
+        }
+    }
+}
+
+#[derive(Clone, Debug, SerialDecodable, SerialEncodable, PartialEq, Eq)]
 pub struct Comment {
     content: String,
     author: String,
     timestamp: Timestamp,
 }
 
+impl From<Comment> for JsonValue {
+    fn from(comment: Comment) -> JsonValue {
+        JsonValue::Object(HashMap::from([
+            ("content".to_string(), JsonValue::String(comment.content.clone())),
+            ("author".to_string(), JsonValue::String(comment.author.clone())),
+            ("timestamp".to_string(), JsonValue::String(comment.timestamp.0.to_string())),
+        ]))
+    }
+}
+
+impl From<JsonValue> for Comment {
+    fn from(value: JsonValue) -> Comment {
+        let map = value.get::<HashMap<String, JsonValue>>().unwrap();
+        Comment {
+            content: map["content"].get().unwrap().clone(),
+            author: map["author"].get().unwrap().clone(),
+            timestamp: Timestamp(
+                u64::from_str_radix(map["timestamp"].get::<String>().unwrap(), 10).unwrap(),
+            ),
+        }
+    }
+}
+
 impl Comment {
     pub fn new(content: &str, author: &str) -> Self {
         Self {
@@ -67,34 +115,129 @@ impl Comment {
     }
 }
 
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, SerialEncodable, SerialDecodable)]
-pub struct TaskEvents(pub Vec<TaskEvent>);
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, SerialEncodable, SerialDecodable)]
-pub struct TaskComments(Vec<Comment>);
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, SerialEncodable, SerialDecodable)]
-pub struct TaskProjects(Vec<String>);
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, SerialEncodable, SerialDecodable)]
-pub struct TaskAssigns(Vec<String>);
-#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, SerialEncodable, SerialDecodable)]
-pub struct TaskTags(Vec<String>);
-
-#[derive(Clone, Debug, Serialize, Deserialize, SerialEncodable, SerialDecodable, PartialEq)]
+#[derive(Clone, Debug, SerialEncodable, SerialDecodable, PartialEq)]
 pub struct TaskInfo {
     pub(crate) ref_id: String,
     pub(crate) workspace: String,
     pub(crate) id: u32,
     pub(crate) title: String,
-    tags: TaskTags,
+    tags: Vec<String>,
     desc: String,
     pub(crate) owner: String,
-    assign: TaskAssigns,
-    project: TaskProjects,
+    assign: Vec<String>,
+    project: Vec<String>,
     due: Option<Timestamp>,
     rank: Option<f32>,
     created_at: Timestamp,
     state: String,
-    pub(crate) events: TaskEvents,
-    comments: TaskComments,
+    pub(crate) events: Vec<TaskEvent>,
+    comments: Vec<Comment>,
+}
+
+impl From<&TaskInfo> for JsonValue {
+    fn from(task: &TaskInfo) -> JsonValue {
+        let ref_id = JsonValue::String(task.ref_id.clone());
+        let workspace = JsonValue::String(task.workspace.clone());
+        let id = JsonValue::Number(task.id.into());
+        let title = JsonValue::String(task.title.clone());
+        let tags: Vec<JsonValue> = task.tags.iter().map(|x| JsonValue::String(x.clone())).collect();
+        let desc = JsonValue::String(task.desc.clone());
+        let owner = JsonValue::String(task.owner.clone());
+
+        let assign: Vec<JsonValue> =
+            task.assign.iter().map(|x| JsonValue::String(x.clone())).collect();
+
+        let project: Vec<JsonValue> =
+            task.project.iter().map(|x| JsonValue::String(x.clone())).collect();
+
+        let due = if let Some(ts) = task.due {
+            JsonValue::String(ts.0.to_string())
+        } else {
+            JsonValue::Null
+        };
+
+        let rank = if let Some(rank) = task.rank {
+            JsonValue::Number(rank.into())
+        } else {
+            JsonValue::Null
+        };
+
+        let created_at = JsonValue::String(task.created_at.0.to_string());
+        let state = JsonValue::String(task.state.clone());
+        let events: Vec<JsonValue> = task.events.iter().map(|x| x.clone().into()).collect();
+        let comments: Vec<JsonValue> = task.comments.iter().map(|x| x.clone().into()).collect();
+
+        JsonValue::Object(HashMap::from([
+            ("ref_id".to_string(), ref_id),
+            ("workspace".to_string(), workspace),
+            ("id".to_string(), id),
+            ("title".to_string(), title),
+            ("tags".to_string(), JsonValue::Array(tags)),
+            ("desc".to_string(), desc),
+            ("owner".to_string(), owner),
+            ("assign".to_string(), JsonValue::Array(assign)),
+            ("project".to_string(), JsonValue::Array(project)),
+            ("due".to_string(), due),
+            ("rank".to_string(), rank),
+            ("created_at".to_string(), created_at),
+            ("state".to_string(), state),
+            ("events".to_string(), JsonValue::Array(events)),
+            ("comments".to_string(), JsonValue::Array(comments)),
+        ]))
+    }
+}
+
+impl From<JsonValue> for TaskInfo {
+    fn from(value: JsonValue) -> TaskInfo {
+        let tags = value["tags"].get::<Vec<JsonValue>>().unwrap();
+        let assign = value["assign"].get::<Vec<JsonValue>>().unwrap();
+        let project = value["project"].get::<Vec<JsonValue>>().unwrap();
+        let events = value["events"].get::<Vec<JsonValue>>().unwrap();
+        let comments = value["comments"].get::<Vec<JsonValue>>().unwrap();
+
+        let due = {
+            if value["due"].is_null() {
+                None
+            } else {
+                let u64_str = value["due"].get::<String>().unwrap();
+                Some(Timestamp(u64::from_str_radix(u64_str, 10).unwrap()))
+            }
+        };
+
+        let rank = {
+            if value["rank"].is_null() {
+                None
+            } else {
+                Some(*value["rank"].get::<f64>().unwrap() as f32)
+            }
+        };
+
+        let created_at = {
+            let u64_str = value["created_at"].get::<String>().unwrap();
+            Timestamp(u64::from_str_radix(u64_str, 10).unwrap())
+        };
+
+        let events: Vec<TaskEvent> = events.iter().map(|x| x.into()).collect();
+        let comments: Vec<Comment> = comments.iter().map(|x| (*x).into()).collect();
+
+        TaskInfo {
+            ref_id: value["ref_id"].get::<String>().unwrap().clone(),
+            workspace: value["workspace"].get::<String>().unwrap().clone(),
+            id: *value["id"].get::<f64>().unwrap() as u32,
+            title: value["title"].get::<String>().unwrap().clone(),
+            tags: tags.iter().map(|x| x.get::<String>().unwrap().clone()).collect(),
+            desc: value["desc"].get::<String>().unwrap().clone(),
+            owner: value["owner"].get::<String>().unwrap().clone(),
+            assign: assign.iter().map(|x| x.get::<String>().unwrap().clone()).collect(),
+            project: project.iter().map(|x| x.get::<String>().unwrap().clone()).collect(),
+            due,
+            rank,
+            created_at,
+            state: value["state"].get::<String>().unwrap().clone(),
+            events,
+            comments,
+        }
+    }
 }
 
 impl TaskInfo {
@@ -133,27 +276,27 @@ impl TaskInfo {
             title: title.into(),
             desc: desc.into(),
             owner: owner.into(),
-            tags: TaskTags(vec![]),
-            assign: TaskAssigns(vec![]),
-            project: TaskProjects(vec![]),
+            tags: vec![],
+            assign: vec![],
+            project: vec![],
             due,
             rank,
             created_at,
             state: "open".into(),
-            comments: TaskComments(vec![]),
-            events: TaskEvents(vec![]),
+            comments: vec![],
+            events: vec![],
         })
     }
 
     pub fn load(ref_id: &str, dataset_path: &Path) -> TaudResult<Self> {
         debug!(target: "tau", "TaskInfo::load()");
-        let task = load_json_file::<Self>(&Self::get_path(ref_id, dataset_path))?;
-        Ok(task)
+        let task = load_json_file(&Self::get_path(ref_id, dataset_path))?;
+        Ok(task.into())
     }
 
     pub fn save(&self, dataset_path: &Path) -> TaudResult<()> {
         debug!(target: "tau", "TaskInfo::save()");
-        save_json_file::<Self>(&Self::get_path(&self.ref_id, dataset_path), self, true)
+        save_json_file(&Self::get_path(&self.ref_id, dataset_path), &self.into(), true)
             .map_err(TaudError::Darkfi)?;
 
         if self.get_state() == "stop" {
@@ -207,29 +350,29 @@ impl TaskInfo {
     pub fn set_tags(&mut self, tags: &[String]) {
         debug!(target: "tau", "TaskInfo::set_tags()");
         for tag in tags.iter() {
-            if tag.starts_with('+') && !self.tags.0.contains(tag) {
-                self.tags.0.push(tag.to_string());
+            if tag.starts_with('+') && !self.tags.contains(tag) {
+                self.tags.push(tag.to_string());
             }
             if tag.starts_with('-') {
                 let t = tag.replace('-', "+");
-                self.tags.0.retain(|tag| tag != &t);
+                self.tags.retain(|tag| tag != &t);
             }
         }
     }
 
     pub fn set_assign(&mut self, assigns: &[String]) {
         debug!(target: "tau", "TaskInfo::set_assign()");
-        self.assign = TaskAssigns(assigns.to_owned());
+        self.assign = assigns.to_owned();
     }
 
     pub fn set_project(&mut self, projects: &[String]) {
         debug!(target: "tau", "TaskInfo::set_project()");
-        self.project = TaskProjects(projects.to_owned());
+        self.project = projects.to_owned();
     }
 
     pub fn set_comment(&mut self, c: Comment) {
         debug!(target: "tau", "TaskInfo::set_comment()");
-        self.comments.0.push(c);
+        self.comments.push(c);
     }
 
     pub fn set_rank(&mut self, r: Option<f32>) {

+ 1 - 1
bin/tau/taud/src/util.rs

@@ -40,7 +40,7 @@ pub fn find_free_id(task_ids: &[u32]) -> u32 {
 pub fn set_event(task_info: &mut TaskInfo, action: &str, author: &str, content: &str) {
     debug!(target: "tau", "TaskInfo::set_event()");
     if !content.is_empty() {
-        task_info.events.0.push(TaskEvent::new(action.into(), author.into(), content.into()));
+        task_info.events.push(TaskEvent::new(action.into(), author.into(), content.into()));
     }
 }