bin/tau: task IDs to be local instead of being written in task itself, and use refids instead

This commit is contained in:
Dastan-glitch
2023-09-22 05:54:16 +03:00
parent 214a4f458d
commit bd82d1c850
9 changed files with 149 additions and 134 deletions

View File

@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use std::{process::exit, sync::Arc};
use std::{collections::HashMap, process::exit, sync::Arc};
use clap::{Parser, Subcommand};
use log::{error, info};
@@ -41,7 +41,7 @@ use drawdown::{drawdown, to_naivedate};
use filter::{apply_filter, get_ids, no_filter_warn};
use primitives::{task_from_cli, State, TaskEvent};
use util::{due_as_timestamp, prompt_text};
use view::{print_task_info, print_task_list};
use view::{find_free_id, print_task_info, print_task_list};
use taud::task_info::TaskInfo;
@@ -181,28 +181,43 @@ fn main() -> Result<()> {
// If not provided we use get_ids() to get them from the daemon.
let ids = get_ids(&mut filters)?;
let ids_clone = ids.clone();
let task_ids = if ids.is_empty() { tau.get_ids().await? } else { ids };
let mut tasks_local_id = HashMap::new();
let mut tasks = if filters.contains(&"state:stop".to_string()) ||
let task_ref_ids = tau.get_ref_ids().await?;
let tasks = if filters.contains(&"state:stop".to_string()) ||
filters.contains(&"all".to_string())
{
tau.get_stop_tasks(None).await?
} else {
vec![]
};
for id in task_ids {
tasks.push(tau.get_task_by_id(id).await?);
let mut store_ids = vec![];
for task in tasks.clone() {
let task_id = find_free_id(&store_ids);
tasks_local_id.insert(task_id as usize, task);
store_ids.push(task_id);
}
for refid in task_ref_ids {
let task_id = find_free_id(&store_ids);
let element = tau.get_task_by_ref_id(&refid).await?;
tasks_local_id.insert(task_id as usize, element);
store_ids.push(task_id);
}
if ids_clone.len() == 1 && args.command.is_none() {
let tsk = tasks[0].clone();
print_task_info(tsk)?;
let id_itself = ids_clone[0] as usize;
let tsk = tasks_local_id.get(&id_itself).unwrap();
print_task_info(id_itself, tsk.clone())?;
return Ok(())
}
for filter in filters {
apply_filter(&mut tasks, &filter);
apply_filter(&mut tasks_local_id.clone().into_values().collect(), &filter);
}
// Parse subcommands
@@ -226,9 +241,8 @@ fn main() -> Result<()> {
let title = task.clone().title;
let task_id = tau.add(task).await?;
if task_id > 0 {
println!("Created task {} \"{}\"", task_id, title);
if tau.add(task).await? {
println!("Created task \"{}\"", title);
}
Ok(())
}
@@ -237,12 +251,13 @@ fn main() -> Result<()> {
if args.filters.is_empty() {
no_filter_warn()
}
let base_task = task_from_cli(values)?;
for task in tasks.clone() {
let res = tau.update(task.id, base_task.clone()).await?;
for (id, task) in tasks_local_id {
let res = tau.update(&task.ref_id, base_task.clone()).await?;
if res {
let tsk = tau.get_task_by_id(task.id).await?;
print_task_info(tsk)?;
let tsk = tau.get_task_by_ref_id(&task.ref_id).await?;
print_task_info(id, tsk)?;
}
}
@@ -253,10 +268,12 @@ fn main() -> Result<()> {
if args.filters.is_empty() {
no_filter_warn()
}
let state = State::Start;
for task in tasks {
if tau.set_state(task.id, &state).await? {
println!("Started task: {:?}", task.id);
for id in ids_clone {
let task = tasks_local_id.get(&(id as usize)).unwrap();
if tau.set_state(&task.ref_id, &state).await? {
println!("Started task: {} with refid: {}", id, task.ref_id);
}
}
@@ -267,10 +284,12 @@ fn main() -> Result<()> {
if args.filters.is_empty() {
no_filter_warn()
}
let state = State::Open;
for task in tasks {
if tau.set_state(task.id, &state).await? {
println!("Opened task: {:?}", task.id);
for id in ids_clone {
let task = tasks_local_id.get(&(id as usize)).unwrap();
if tau.set_state(&task.ref_id, &state).await? {
println!("Opened task: {} with refid: {}", id, task.ref_id);
}
}
@@ -281,10 +300,12 @@ fn main() -> Result<()> {
if args.filters.is_empty() {
no_filter_warn()
}
let state = State::Pause;
for task in tasks {
if tau.set_state(task.id, &state).await? {
println!("Paused task: {:?}", task.id);
for id in ids_clone {
let task = tasks_local_id.get(&(id as usize)).unwrap();
if tau.set_state(&task.ref_id, &state).await? {
println!("Paused task: {} with refid: {}", id, task.ref_id);
}
}
@@ -295,10 +316,12 @@ fn main() -> Result<()> {
if args.filters.is_empty() {
no_filter_warn()
}
let state = State::Stop;
for task in tasks {
if tau.set_state(task.id, &state).await? {
println!("Stopped task: {}", task.id);
for id in ids_clone {
let task = tasks_local_id.get(&(id as usize)).unwrap();
if tau.set_state(&task.ref_id, &state).await? {
println!("Stopped task: {} with refid: {}", id, task.ref_id);
}
}
@@ -309,7 +332,9 @@ fn main() -> Result<()> {
if args.filters.is_empty() {
no_filter_warn()
}
for task in tasks {
for id in ids_clone {
let task = tasks_local_id.get(&(id as usize)).unwrap();
let comment = if content.is_empty() {
prompt_text(task.clone(), "comment")?
} else {
@@ -321,19 +346,20 @@ fn main() -> Result<()> {
exit(1)
}
let res = tau.set_comment(task.id, comment.unwrap().trim()).await?;
let res = tau.set_comment(&task.ref_id, comment.unwrap().trim()).await?;
if res {
let tsk = tau.get_task_by_id(task.id).await?;
print_task_info(tsk)?;
let tsk = tau.get_task_by_ref_id(&task.ref_id).await?;
print_task_info(id as usize, tsk)?;
}
}
Ok(())
}
TauSubcommand::Info => {
for task in tasks {
let task = tau.get_task_by_id(task.id).await?;
print_task_info(task)?;
for id in ids_clone {
let task = tasks_local_id.get(&(id as usize)).unwrap();
let task = tau.get_task_by_ref_id(&task.ref_id).await?;
print_task_info(id as usize, task)?;
}
Ok(())
}
@@ -385,9 +411,9 @@ fn main() -> Result<()> {
drawdown(date, tasks, assignee)?;
}
None => {
let ws = tau.get_ws().await?;
let tasks = tau.get_stop_tasks(None).await?;
print_task_list(tasks, ws)?;
let _ws = tau.get_ws().await?;
let _tasks = tau.get_stop_tasks(None).await?;
// print_task_list(tasks, ws)?;
}
}
@@ -396,12 +422,12 @@ fn main() -> Result<()> {
TauSubcommand::List => {
let ws = tau.get_ws().await?;
print_task_list(tasks, ws)
print_task_list(tasks_local_id, ws)
}
},
None => {
let ws = tau.get_ws().await?;
print_task_list(tasks, ws)
print_task_list(tasks_local_id, ws)
}
}?;

View File

@@ -37,7 +37,6 @@ impl From<BaseTask> for TaskInfo {
Self {
ref_id: String::default(),
workspace: String::default(),
id: u32::default(),
title: value.title,
tags: value.tags,
desc: String::default(),

View File

@@ -31,7 +31,7 @@ impl Tau {
}
/// Add a new task.
pub async fn add(&self, task: BaseTask) -> Result<u32> {
pub async fn add(&self, task: BaseTask) -> Result<bool> {
let mut params = vec![
JsonValue::String(task.title.clone()),
JsonValue::Array(task.tags.iter().map(|x| JsonValue::String(x.clone())).collect()),
@@ -55,26 +55,26 @@ impl Tau {
let rep = self.rpc_client.request(req).await?;
debug!("Got reply: {:?}", rep);
Ok(*rep.get::<f64>().unwrap() as u32)
Ok(*rep.get::<bool>().unwrap())
}
/// Get current open tasks ids.
pub async fn get_ids(&self) -> Result<Vec<u32>> {
let req = JsonRequest::new("get_ids", vec![]);
pub async fn get_ref_ids(&self) -> Result<Vec<String>> {
let req = JsonRequest::new("get_ref_ids", vec![]);
let rep = self.rpc_client.request(req).await?;
debug!("Got reply: {:?}", rep);
let mut ret = vec![];
for i in rep.get::<Vec<JsonValue>>().unwrap() {
ret.push(*i.get::<f64>().unwrap() as u32)
ret.push(i.get::<String>().unwrap().to_string())
}
Ok(ret)
}
/// Update existing task given it's ID and some params.
pub async fn update(&self, id: u32, task: BaseTask) -> Result<bool> {
pub async fn update(&self, ref_id: &str, task: BaseTask) -> Result<bool> {
let mut params = vec![
JsonValue::String(task.title.clone()),
JsonValue::Array(task.tags.iter().map(|x| JsonValue::String(x.clone())).collect()),
@@ -96,7 +96,7 @@ impl Tau {
let req = JsonRequest::new(
"update",
vec![JsonValue::Number(id.into()), JsonValue::Array(params)],
vec![JsonValue::String(ref_id.into()), JsonValue::Array(params)],
);
let rep = self.rpc_client.request(req).await?;
@@ -105,10 +105,10 @@ impl Tau {
}
/// Set the state for a task.
pub async fn set_state(&self, id: u32, state: &State) -> Result<bool> {
pub async fn set_state(&self, ref_id: &str, state: &State) -> Result<bool> {
let req = JsonRequest::new(
"set_state",
vec![JsonValue::Number(id.into()), JsonValue::String(state.to_string())],
vec![JsonValue::String(ref_id.into()), JsonValue::String(state.to_string())],
);
let rep = self.rpc_client.request(req).await?;
@@ -117,10 +117,10 @@ impl Tau {
}
/// Set a comment for a task.
pub async fn set_comment(&self, id: u32, content: &str) -> Result<bool> {
pub async fn set_comment(&self, ref_id: &str, content: &str) -> Result<bool> {
let req = JsonRequest::new(
"set_comment",
vec![JsonValue::Number(id.into()), JsonValue::String(content.to_string())],
vec![JsonValue::String(ref_id.into()), JsonValue::String(content.to_string())],
);
let rep = self.rpc_client.request(req).await?;
@@ -129,8 +129,8 @@ impl Tau {
}
/// Get task data by its ID.
pub async fn get_task_by_id(&self, id: u32) -> Result<TaskInfo> {
let req = JsonRequest::new("get_task_by_id", vec![JsonValue::Number(id.into())]);
pub async fn get_task_by_ref_id(&self, ref_id: &str) -> Result<TaskInfo> {
let req = JsonRequest::new("get_task_by_ref_id", vec![JsonValue::String(ref_id.into())]);
let rep = self.rpc_client.request(req).await?;
debug!("Got reply: {:?}", rep);

View File

@@ -75,7 +75,7 @@ pub fn prompt_text(task_info: TaskInfo, what: &str) -> Result<Option<String>> {
writeln!(file, "\n# ------------------------ >8 ------------------------")?;
writeln!(file, "# Do not modify or remove the line above.")?;
writeln!(file, "# Everything below it will be ignored.")?;
writeln!(file, "\n{}", taskinfo_table(task_info.clone())?)?;
writeln!(file, "\n{}", taskinfo_table(0, task_info.clone())?)?;
writeln!(file, "{}", events_table(task_info.clone())?)?;
writeln!(file, "{}", comments_table(task_info)?)?;

View File

@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use std::{cmp::Ordering, fmt::Write, str::FromStr};
use std::{cmp::Ordering, collections::HashMap, fmt::Write, str::FromStr};
use prettytable::{
format::{consts::FORMAT_NO_COLSEP, FormatBuilder, LinePosition, LineSeparator},
@@ -34,8 +34,8 @@ use crate::{
TaskEvent,
};
pub fn print_task_list(tasks: Vec<TaskInfo>, ws: String) -> Result<()> {
let mut tasks = tasks;
pub fn print_task_list(tasks_map: HashMap<usize, TaskInfo>, ws: String) -> Result<()> {
let mut tasks = tasks_map.clone().into_values().collect::<Vec<TaskInfo>>();
let mut table = Table::new();
table.set_format(
@@ -70,7 +70,7 @@ pub fn print_task_list(tasks: Vec<TaskInfo>, ws: String) -> Result<()> {
min_rank = last.rank;
}
for task in tasks {
for (task_id, task) in tasks_map {
let state = State::from_str(&task.state.clone())?;
let (max_style, min_style, mid_style, gen_style) = if state.is_start() {
@@ -96,7 +96,7 @@ pub fn print_task_list(tasks: Vec<TaskInfo>, ws: String) -> Result<()> {
};
table.add_row(Row::new(vec![
Cell::new(&task.id.to_string()).style_spec(gen_style),
Cell::new(&task_id.to_string()).style_spec(gen_style),
Cell::new(&task.title).style_spec(gen_style),
Cell::new(&print_tags.join(", ")).style_spec(gen_style),
Cell::new(&task.project.join(", ")).style_spec(gen_style),
@@ -136,7 +136,7 @@ pub fn print_task_list(tasks: Vec<TaskInfo>, ws: String) -> Result<()> {
Ok(())
}
pub fn taskinfo_table(taskinfo: TaskInfo) -> Result<Table> {
pub fn taskinfo_table(id: usize, taskinfo: TaskInfo) -> Result<Table> {
let due_ = match taskinfo.due {
Some(ts) => ts.0,
None => 0,
@@ -149,7 +149,7 @@ pub fn taskinfo_table(taskinfo: TaskInfo) -> Result<Table> {
let mut table = table!(
[Bd => "ref_id", &taskinfo.ref_id],
["workspace", &taskinfo.workspace],
[Bd =>"id", &taskinfo.id.to_string()],
[Bd =>"id", &id.to_string()],
["owner", &taskinfo.owner],
[Bd =>"title", &taskinfo.title],
["tags", &taskinfo.tags.join(", ")],
@@ -189,8 +189,8 @@ pub fn comments_table(taskinfo: TaskInfo) -> Result<Table> {
Ok(comments_table)
}
pub fn print_task_info(taskinfo: TaskInfo) -> Result<()> {
let table = taskinfo_table(taskinfo.clone())?;
pub fn print_task_info(id: usize, taskinfo: TaskInfo) -> Result<()> {
let table = taskinfo_table(id, taskinfo.clone())?;
table.printstd();
let events_table = events_table(taskinfo.clone())?;
@@ -285,3 +285,12 @@ pub fn comments_as_string(events: Vec<TaskEvent>) -> (String, String) {
}
(events_str, timestamps_str)
}
pub fn find_free_id(task_ids: &[u32]) -> u32 {
for i in 1.. {
if !task_ids.contains(&i) {
return i
}
}
1
}

View File

@@ -45,7 +45,7 @@ use taud::{
error::{to_json_result, TaudError, TaudResult},
month_tasks::MonthTasks,
task_info::{Comment, TaskInfo},
util::{find_free_id, set_event},
util::set_event,
};
pub struct JsonRpcInterface {
@@ -64,11 +64,11 @@ impl RequestHandler for JsonRpcInterface {
async fn handle_request(&self, req: JsonRequest) -> JsonResult {
let rep = match req.method.as_str() {
"add" => self.add(req.params).await,
"get_ids" => self.get_ids(req.params).await,
"get_ref_ids" => self.get_ref_ids(req.params).await,
"update" => self.update(req.params).await,
"set_state" => self.set_state(req.params).await,
"set_comment" => self.set_comment(req.params).await,
"get_task_by_id" => self.get_task_by_id(req.params).await,
"get_task_by_ref_id" => self.get_task_by_ref_id(req.params).await,
"switch_ws" => self.switch_ws(req.params).await,
"get_ws" => self.get_ws(req.params).await,
"export" => self.export_to(req.params).await,
@@ -252,31 +252,30 @@ impl JsonRpcInterface {
&self.nickname,
due,
rank,
&self.dataset_path,
)?;
new_task.set_project(&projects);
new_task.set_assign(&assigns);
new_task.set_tags(&tags);
self.notify_queue_sender.send(new_task.clone()).await.map_err(Error::from)?;
Ok(JsonValue::Number(new_task.id.into()))
Ok(JsonValue::Boolean(true))
}
// RPCAPI:
// List tasks
// --> {"jsonrpc": "2.0", "method": "get_ids", "params": [], "id": 1}
// <-- {"jsonrpc": "2.0", "result": [task_id, ...], "id": 1}
async fn get_ids(&self, params: JsonValue) -> TaudResult<JsonValue> {
async fn get_ref_ids(&self, params: JsonValue) -> TaudResult<JsonValue> {
let params = params.get::<Vec<JsonValue>>().unwrap();
debug!(target: "tau", "JsonRpc::get_ids() params {:?}", params);
let ws = self.workspace.lock().await.clone();
let tasks = MonthTasks::load_current_tasks(&self.dataset_path, ws, false)?;
let task_ids: Vec<JsonValue> =
tasks.iter().map(|task| JsonValue::Number(task.get_id().into())).collect();
let task_ref_ids: Vec<JsonValue> =
tasks.iter().map(|task| JsonValue::String(task.get_ref_id())).collect();
Ok(JsonValue::Array(task_ids))
Ok(JsonValue::Array(task_ref_ids))
}
// RPCAPI:
@@ -287,14 +286,14 @@ impl JsonRpcInterface {
let params = params.get::<Vec<JsonValue>>().unwrap();
debug!(target: "tau", "JsonRpc::update() params {:?}", params);
if params.len() != 2 || !params[0].is_number() || !params[1].is_object() {
if params.len() != 2 || !params[0].is_string() || !params[1].is_object() {
return Err(TaudError::InvalidData("len of params should be 2".into()))
}
let ws = self.workspace.lock().await.clone();
let task = self.check_params_for_update(
*params[0].get::<f64>().unwrap() as u32,
params[0].get::<String>().unwrap(),
params[1].get::<HashMap<String, JsonValue>>().unwrap(),
ws,
)?;
@@ -315,7 +314,7 @@ impl JsonRpcInterface {
let params = params.get::<Vec<JsonValue>>().unwrap();
debug!(target: "tau", "JsonRpc::set_state() params {:?}", params);
if params.len() != 2 || !params[0].is_number() || !params[1].is_string() {
if params.len() != 2 || !params[0].is_string() || !params[1].is_string() {
return Err(TaudError::InvalidData("len of params should be 2".into()))
}
@@ -323,7 +322,7 @@ impl JsonRpcInterface {
let ws = self.workspace.lock().await.clone();
let mut task: TaskInfo =
self.load_task_by_id(*params[0].get::<f64>().unwrap() as u32, ws)?;
self.load_task_by_ref_id(params[0].get::<String>().unwrap(), ws)?;
if states.contains(&state.as_str()) {
task.set_state(state);
@@ -343,15 +342,15 @@ impl JsonRpcInterface {
let params = params.get::<Vec<JsonValue>>().unwrap();
debug!(target: "tau", "JsonRpc::set_comment() params {:?}", params);
if params.len() != 2 || !params[0].is_number() || !params[1].is_string() {
if params.len() != 2 || !params[0].is_string() || !params[1].is_string() {
return Err(TaudError::InvalidData("len of params should be 2".into()))
}
let id = *params[0].get::<f64>().unwrap() as u32;
let ref_id = params[0].get::<String>().unwrap();
let comment_content = params[1].get::<String>().unwrap();
let ws = self.workspace.lock().await.clone();
let mut task: TaskInfo = self.load_task_by_id(id, ws)?;
let mut task: TaskInfo = self.load_task_by_ref_id(ref_id, ws)?;
task.set_comment(Comment::new(comment_content, &self.nickname));
set_event(&mut task, "comment", &self.nickname, comment_content);
@@ -365,16 +364,16 @@ impl JsonRpcInterface {
// Get a task by id.
// --> {"jsonrpc": "2.0", "method": "get_task_by_id", "params": [task_id], "id": 1}
// <-- {"jsonrpc": "2.0", "result": "task", "id": 1}
async fn get_task_by_id(&self, params: JsonValue) -> TaudResult<JsonValue> {
async fn get_task_by_ref_id(&self, params: JsonValue) -> TaudResult<JsonValue> {
let params = params.get::<Vec<JsonValue>>().unwrap();
debug!(target: "tau", "JsonRpc::get_task_by_id() params {:?}", params);
if params.len() != 1 || !params[0].is_number() {
if params.len() != 1 || !params[0].is_string() {
return Err(TaudError::InvalidData("len of params should be 1".into()))
}
let ws = self.workspace.lock().await.clone();
let task: TaskInfo = self.load_task_by_id(*params[0].get::<f64>().unwrap() as u32, ws)?;
let task: TaskInfo = self.load_task_by_ref_id(params[0].get::<String>().unwrap(), ws)?;
let task: JsonValue = (&task).into();
Ok(task)
@@ -502,15 +501,9 @@ impl JsonRpcInterface {
let path = expand_path(path)?.join("exported_tasks");
let ws = self.workspace.lock().await.clone();
let mut task_ids: Vec<u32> =
MonthTasks::load_current_tasks(&self.dataset_path, ws.clone(), false)?
.into_iter()
.map(|t| t.id)
.collect();
let imported_tasks = MonthTasks::load_current_tasks(&path, ws.clone(), true)?;
for mut task in imported_tasks {
for task in imported_tasks {
if MonthTasks::load_current_tasks(&self.dataset_path, ws.clone(), false)?
.into_iter()
.map(|t| t.ref_id)
@@ -519,27 +512,25 @@ impl JsonRpcInterface {
continue
}
task.id = find_free_id(&task_ids);
task_ids.push(task.id);
self.notify_queue_sender.send(task).await.map_err(Error::from)?;
}
Ok(JsonValue::Boolean(true))
}
fn load_task_by_id(&self, task_id: u32, ws: String) -> TaudResult<TaskInfo> {
fn load_task_by_ref_id(&self, task_ref_id: &str, ws: String) -> TaudResult<TaskInfo> {
let tasks = MonthTasks::load_current_tasks(&self.dataset_path, ws, false)?;
let task = tasks.into_iter().find(|t| (t.get_id()) == task_id);
let task = tasks.into_iter().find(|t| (t.get_ref_id()) == task_ref_id);
task.ok_or(TaudError::InvalidId)
}
fn check_params_for_update(
&self,
task_id: u32,
task_ref_id: &str,
fields: &HashMap<String, JsonValue>,
ws: String,
) -> TaudResult<TaskInfo> {
let mut task: TaskInfo = self.load_task_by_id(task_id, ws)?;
let mut task: TaskInfo = self.load_task_by_ref_id(task_ref_id, ws)?;
if fields.contains_key("title") {
let title = fields["title"].get::<String>().unwrap();

View File

@@ -273,7 +273,6 @@ mod tests {
"NICKNAME",
None,
Some(0.0),
&dataset_path,
)?;
task.save(&dataset_path)?;
@@ -321,7 +320,6 @@ mod tests {
"NICKNAME",
None,
Some(0.0),
&dataset_path,
)?;
task.save(&dataset_path)?;

View File

@@ -39,7 +39,6 @@ use darkfi::{
use crate::{
error::{TaudError, TaudResult},
month_tasks::MonthTasks,
util::find_free_id,
};
pub enum State {
@@ -189,7 +188,6 @@ impl Comment {
pub struct TaskInfo {
pub ref_id: String,
pub workspace: String,
pub id: u32,
pub title: String,
pub tags: Vec<String>,
pub desc: String,
@@ -208,7 +206,6 @@ 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());
@@ -240,7 +237,6 @@ impl From<&TaskInfo> for JsonValue {
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),
@@ -293,7 +289,6 @@ impl From<JsonValue> for TaskInfo {
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(),
@@ -318,20 +313,17 @@ impl TaskInfo {
owner: &str,
due: Option<Timestamp>,
rank: Option<f32>,
dataset_path: &Path,
) -> TaudResult<Self> {
// generate ref_id
let ref_id = gen_id(30);
let created_at = Timestamp::current_time();
let task_ids: Vec<u32> =
MonthTasks::load_current_tasks(dataset_path, workspace.clone(), false)?
.into_iter()
.map(|t| t.id)
.collect();
let id: u32 = find_free_id(&task_ids);
// let task_ids: Vec<u32> =
// MonthTasks::load_current_tasks(dataset_path, workspace.clone(), false)?
// .into_iter()
// .map(|t| t.id)
// .collect();
if let Some(d) = &due {
if *d < Timestamp::current_time() {
@@ -342,7 +334,6 @@ impl TaskInfo {
Ok(Self {
ref_id,
workspace,
id,
title: title.into(),
desc: desc.into(),
owner: owner.into(),
@@ -402,9 +393,9 @@ impl TaskInfo {
dataset_path.join("task").join(ref_id)
}
pub fn get_id(&self) -> u32 {
debug!(target: "tau", "TaskInfo::get_id()");
self.id
pub fn get_ref_id(&self) -> String {
debug!(target: "tau", "TaskInfo::get_ref_id()");
self.ref_id.clone()
}
pub fn set_title(&mut self, title: &str) {

View File

@@ -27,7 +27,7 @@ use log::debug;
use darkfi::{Error, Result};
use crate::task_info::{TaskEvent, TaskInfo};
/*
pub fn find_free_id(task_ids: &[u32]) -> u32 {
for i in 1.. {
if !task_ids.contains(&i) {
@@ -36,6 +36,7 @@ pub fn find_free_id(task_ids: &[u32]) -> u32 {
}
1
}
*/
pub fn set_event(task_info: &mut TaskInfo, action: &str, author: &str, content: &str) {
debug!(target: "tau", "TaskInfo::set_event()");
@@ -53,29 +54,29 @@ pub fn pipe_write<P: AsRef<Path>>(path: P) -> Result<File> {
.map_err(Error::from)
}
#[cfg(test)]
mod tests {
use super::*;
// #[cfg(test)]
// mod tests {
// use super::*;
use darkfi::Result;
#[test]
fn find_free_id_test() -> Result<()> {
let mut ids: Vec<u32> = vec![1, 3, 8, 9, 10, 3];
let ids_empty: Vec<u32> = vec![];
let ids_duplicate: Vec<u32> = vec![1; 100];
// use darkfi::Result;
// #[test]
// fn find_free_id_test() -> Result<()> {
// let mut ids: Vec<u32> = vec![1, 3, 8, 9, 10, 3];
// let ids_empty: Vec<u32> = vec![];
// let ids_duplicate: Vec<u32> = vec![1; 100];
let find_id = find_free_id(&ids);
// let find_id = find_free_id(&ids);
assert_eq!(find_id, 2);
// assert_eq!(find_id, 2);
ids.push(find_id);
// ids.push(find_id);
assert_eq!(find_free_id(&ids), 4);
// assert_eq!(find_free_id(&ids), 4);
assert_eq!(find_free_id(&ids_empty), 1);
// assert_eq!(find_free_id(&ids_empty), 1);
assert_eq!(find_free_id(&ids_duplicate), 2);
// assert_eq!(find_free_id(&ids_duplicate), 2);
Ok(())
}
}
// Ok(())
// }
// }