1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
use fake::Dummy; use fake::Fake; use serde::Deserialize; use serde::Serialize; use serde_json::Value; use crate::types::ResultDynError; #[derive(Serialize, Deserialize, Debug)] pub struct TaskFamily { pub parent_task: Task, pub children: Vec<TaskFamily>, } impl TaskFamily { pub fn json_string(task_families: &[TaskFamily]) -> ResultDynError<String> { return serde_json::to_string(task_families).map_err(failure::Error::from); } } #[derive(Clone, Debug, Serialize, Deserialize, Dummy)] pub struct Task { pub id: String, pub task_type: String, pub phid: String, pub name: String, pub description: String, pub author_phid: String, pub assigned_phid: Option<String>, pub status: String, pub priority: String, pub point: Option<u64>, pub project_phids: Vec<String>, pub board: Option<Board>, pub created_at: u64, pub updated_at: u64, } impl Task { pub fn from_json(v: &Value) -> Task { let project_phids: &Vec<Value> = match &v["attachments"]["projects"]["projectPHIDs"] { Value::Array(arr) => arr, _ => panic!( "Project phids is not an array {:?}", v["attachments"]["projects"]["projectPHIDs"] ), }; let project_phids: Vec<String> = project_phids.iter().map(json_to_string).collect(); let board: Option<&Value> = Task::guess_board_from_projects(&v["attachments"]["columns"]["boards"], &project_phids); let fields: &Value = &v["fields"]; let task = Task { id: format!("{}", v["id"].as_u64().unwrap()), task_type: json_to_string(&v["type"]), phid: json_to_string(&v["phid"]), name: json_to_string(&fields["name"]), description: json_to_string(&fields["description"]["raw"]), author_phid: json_to_string(&fields["authorPHID"]), assigned_phid: fields["ownerPHID"].as_str().map(Into::into), status: json_to_string(&fields["status"]["value"]), priority: json_to_string(&fields["priority"]["name"]), point: fields["points"].as_u64(), project_phids, board: board.map(|board: &Value| { return Board { id: board["id"].as_u64().unwrap(), phid: board["phid"].as_str().unwrap().into(), name: board["name"].as_str().unwrap().into(), }; }), created_at: fields["dateCreated"].as_u64().unwrap(), updated_at: fields["dateModified"].as_u64().unwrap(), }; return task; } pub fn guess_board_from_projects<'a>( boards: &'a Value, project_phids: &[String], ) -> Option<&'a Value> { return project_phids .iter() .find(|phid| { return boards[phid] != Value::Null; }) .map(|phid| &boards[&phid]["columns"][0]); } } fn json_to_string(v: &Value) -> String { return v.as_str().unwrap().into(); } #[derive(Clone, Debug, Serialize, Deserialize, Dummy)] pub struct Board { pub id: u64, pub phid: String, pub name: String, } #[derive(Clone, Debug, Serialize, Deserialize, Dummy)] pub struct Watchlist { pub id: Option<String>, pub name: String, pub tasks: Vec<Task>, } #[derive(Clone, Debug, Serialize, Deserialize, Dummy)] pub struct User { pub id: String, pub phid: String, pub username: String, pub name: String, pub created_at: u64, pub updated_at: u64, } impl User { pub fn from_json(v: &Value) -> User { let fields: &Value = &v["fields"]; return User { id: format!("{}", v["id"].as_u64().unwrap()), phid: json_to_string(&v["phid"]), username: json_to_string(&fields["username"]), name: json_to_string(&fields["realName"]), created_at: fields["dateCreated"].as_u64().unwrap(), updated_at: fields["dateModified"].as_u64().unwrap(), }; } }