use chrono::{DateTime, Utc};
use serde_json::{Value, json};
use uuid::Uuid;
pub fn create_minimal_task(
actions: Option<Vec<Value>>,
messages: Option<Vec<Value>>,
start_date: Option<DateTime<Utc>>,
complete_date: Option<DateTime<Utc>>,
) -> Result<Value, String> {
let mut task = json!({
"$schema": "https://hai.ai/schemas/task/v1/task.schema.json",
"jacsTaskState": "creating",
});
if let Some(actions) = actions {
task["jacsTaskActionsDesired"] = json!(actions);
}
if let Some(messages) = messages {
task["jacsTaskMessages"] = json!(messages);
}
if let Some(start_date) = start_date {
task["jacsTaskStartDate"] = json!(start_date.to_rfc3339());
}
if let Some(complete_date) = complete_date {
task["jacsTaskCompleteDate"] = json!(complete_date.to_rfc3339());
}
task["id"] = json!(Uuid::new_v4().to_string());
task["jacsType"] = json!("task");
task["jacsLevel"] = json!("config");
Ok(task)
}
pub fn add_action_to_task(task: &mut Value, action: Value) -> Result<(), String> {
if task.get("jacsTaskActionsDesired").is_none() {
task["jacsTaskActionsDesired"] = json!([]);
}
task["jacsTaskActionsDesired"]
.as_array_mut()
.ok_or_else(|| "Invalid task format".to_string())?
.push(action);
Ok(())
}
pub fn update_action_in_task(
task: &mut Value,
old_action: Value,
new_action: Value,
) -> Result<(), String> {
let actions = task["jacsTaskActionsDesired"]
.as_array_mut()
.ok_or_else(|| "Invalid task format".to_string())?;
let index = actions
.iter()
.position(|a| a == &old_action)
.ok_or_else(|| "Action not found".to_string())?;
actions[index] = new_action;
Ok(())
}
pub fn remove_action_from_task(task: &mut Value, action: Value) -> Result<(), String> {
let actions = task["jacsTaskActionsDesired"]
.as_array_mut()
.ok_or_else(|| "Invalid task format".to_string())?;
let index = actions
.iter()
.position(|a| a == &action)
.ok_or_else(|| "Action not found".to_string())?;
actions.remove(index);
Ok(())
}
pub fn update_task_state(task: &mut Value, new_state: &str) -> Result<(), String> {
let allowed_states = ["open", "editlock", "closed"];
if !allowed_states.contains(&new_state) {
return Err(format!("Invalid task state: {}", new_state));
}
task["jacsTaskState"] = json!(new_state);
Ok(())
}
pub fn update_task_start_date(
task: &mut Value,
new_start_date: DateTime<Utc>,
) -> Result<(), String> {
task["jacsTaskStartDate"] = json!(new_start_date.to_rfc3339());
Ok(())
}
pub fn remove_task_start_date(task: &mut Value) -> Result<(), String> {
task.as_object_mut()
.ok_or_else(|| "Invalid task format".to_string())?
.remove("jacsTaskStartDate");
Ok(())
}
pub fn update_task_complete_date(
task: &mut Value,
new_complete_date: DateTime<Utc>,
) -> Result<(), String> {
task["jacsTaskCompleteDate"] = json!(new_complete_date.to_rfc3339());
Ok(())
}
pub fn remove_task_complete_date(task: &mut Value) -> Result<(), String> {
task.as_object_mut()
.ok_or_else(|| "Invalid task format".to_string())?
.remove("jacsTaskCompleteDate");
Ok(())
}
pub fn add_subtask_to_task(task: &mut Value, subtask_id: &str) -> Result<(), String> {
if task.get("jacsTaskSubTaskOf").is_none() {
task["jacsTaskSubTaskOf"] = json!([]);
}
task["jacsTaskSubTaskOf"]
.as_array_mut()
.ok_or_else(|| "Invalid task format".to_string())?
.push(json!(subtask_id));
Ok(())
}
pub fn remove_subtask_from_task(task: &mut Value, subtask_id: &str) -> Result<(), String> {
let subtasks = task["jacsTaskSubTaskOf"]
.as_array_mut()
.ok_or_else(|| "Invalid task format".to_string())?;
let index = subtasks
.iter()
.position(|s| s == subtask_id)
.ok_or_else(|| "Subtask not found".to_string())?;
subtasks.remove(index);
Ok(())
}
pub fn add_copy_task_to_task(task: &mut Value, copy_task_id: &str) -> Result<(), String> {
if task.get("jacsTaskCopyOf").is_none() {
task["jacsTaskCopyOf"] = json!([]);
}
task["jacsTaskCopyOf"]
.as_array_mut()
.ok_or_else(|| "Invalid task format".to_string())?
.push(json!(copy_task_id));
Ok(())
}
pub fn remove_copy_task_from_task(task: &mut Value, copy_task_id: &str) -> Result<(), String> {
let copy_tasks = task["jacsTaskCopyOf"]
.as_array_mut()
.ok_or_else(|| "Invalid task format".to_string())?;
let index = copy_tasks
.iter()
.position(|c| c == copy_task_id)
.ok_or_else(|| "Copy task not found".to_string())?;
copy_tasks.remove(index);
Ok(())
}
pub fn add_merged_task_to_task(task: &mut Value, merged_task_id: &str) -> Result<(), String> {
if task.get("jacsTaskMergedTasks").is_none() {
task["jacsTaskMergedTasks"] = json!([]);
}
task["jacsTaskMergedTasks"]
.as_array_mut()
.ok_or_else(|| "Invalid task format".to_string())?
.push(json!(merged_task_id));
Ok(())
}
pub fn remove_merged_task_from_task(task: &mut Value, merged_task_id: &str) -> Result<(), String> {
let merged_tasks = task["jacsTaskMergedTasks"]
.as_array_mut()
.ok_or_else(|| "Invalid task format".to_string())?;
let index = merged_tasks
.iter()
.position(|m| m == merged_task_id)
.ok_or_else(|| "Merged task not found".to_string())?;
merged_tasks.remove(index);
Ok(())
}