use serde::{Deserialize, Serialize};
use super::common::{Gid, ResourceRef, UserRef};
use super::custom_field::CustomFieldValue;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Task {
pub gid: Gid,
pub name: String,
pub resource_type: Option<String>,
#[serde(default)]
pub completed: bool,
pub completed_at: Option<String>,
pub completed_by: Option<UserRef>,
pub assignee: Option<UserRef>,
pub due_on: Option<String>,
pub due_at: Option<String>,
pub start_on: Option<String>,
pub start_at: Option<String>,
pub notes: Option<String>,
pub html_notes: Option<String>,
pub created_at: Option<String>,
pub created_by: Option<UserRef>,
pub modified_at: Option<String>,
pub permalink_url: Option<String>,
pub parent: Option<TaskRef>,
#[serde(default)]
pub num_likes: u32,
#[serde(default)]
pub num_subtasks: u32,
#[serde(default)]
pub liked: bool,
#[serde(default)]
pub projects: Vec<ResourceRef>,
pub workspace: Option<ResourceRef>,
#[serde(default)]
pub tags: Vec<ResourceRef>,
#[serde(default)]
pub memberships: Vec<TaskMembership>,
pub assignee_section: Option<ResourceRef>,
#[serde(default)]
pub custom_fields: Vec<CustomFieldValue>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TaskRef {
pub gid: Gid,
pub name: Option<String>,
pub resource_type: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TaskMembership {
pub project: ResourceRef,
pub section: Option<ResourceRef>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TaskDependency {
pub gid: Gid,
pub name: Option<String>,
pub resource_type: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_deserialize_task() {
let json = r#"{
"gid": "123",
"name": "My Task",
"completed": false,
"due_on": "2024-01-15",
"notes": "Task description"
}"#;
let task: Task = serde_json::from_str(json).unwrap();
assert_eq!(task.gid, "123");
assert_eq!(task.name, "My Task");
assert!(!task.completed);
assert_eq!(task.due_on, Some("2024-01-15".to_string()));
}
#[test]
fn test_deserialize_task_with_assignee() {
let json = r#"{
"gid": "456",
"name": "Assigned Task",
"completed": true,
"assignee": {
"gid": "789",
"name": "John Doe"
}
}"#;
let task: Task = serde_json::from_str(json).unwrap();
assert!(task.completed);
assert!(task.assignee.is_some());
assert_eq!(task.assignee.unwrap().name, Some("John Doe".to_string()));
}
#[test]
fn test_deserialize_task_ref() {
let json = r#"{
"gid": "123",
"name": "Task Name",
"resource_type": "task"
}"#;
let task_ref: TaskRef = serde_json::from_str(json).unwrap();
assert_eq!(task_ref.gid, "123");
assert_eq!(task_ref.name, Some("Task Name".to_string()));
}
#[test]
fn test_deserialize_task_membership() {
let json = r#"{
"project": {
"gid": "111",
"name": "Project A"
},
"section": {
"gid": "222",
"name": "In Progress"
}
}"#;
let membership: TaskMembership = serde_json::from_str(json).unwrap();
assert_eq!(membership.project.gid, "111");
assert!(membership.section.is_some());
}
}