use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use super::Activity;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Task {
pub id: String,
pub name: String,
pub category: String,
pub priority: i32,
pub deadline: Option<i64>,
pub release_time: Option<i64>,
pub activities: Vec<Activity>,
pub attributes: HashMap<String, String>,
}
impl Task {
pub fn new(id: impl Into<String>) -> Self {
Self {
id: id.into(),
name: String::new(),
category: String::new(),
priority: 0,
deadline: None,
release_time: None,
activities: Vec::new(),
attributes: HashMap::new(),
}
}
pub fn with_name(mut self, name: impl Into<String>) -> Self {
self.name = name.into();
self
}
pub fn with_category(mut self, category: impl Into<String>) -> Self {
self.category = category.into();
self
}
pub fn with_priority(mut self, priority: i32) -> Self {
self.priority = priority;
self
}
pub fn with_deadline(mut self, deadline_ms: i64) -> Self {
self.deadline = Some(deadline_ms);
self
}
pub fn with_release_time(mut self, release_ms: i64) -> Self {
self.release_time = Some(release_ms);
self
}
pub fn with_activity(mut self, activity: Activity) -> Self {
self.activities.push(activity);
self
}
pub fn with_attribute(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.attributes.insert(key.into(), value.into());
self
}
pub fn total_duration_ms(&self) -> i64 {
self.activities.iter().map(|a| a.duration.total_ms()).sum()
}
pub fn has_activities(&self) -> bool {
!self.activities.is_empty()
}
pub fn activity_count(&self) -> usize {
self.activities.len()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::models::ActivityDuration;
#[test]
fn test_task_builder() {
let task = Task::new("J1")
.with_name("Job 1")
.with_category("TypeA")
.with_priority(10)
.with_deadline(100_000)
.with_release_time(0)
.with_attribute("customer", "ACME");
assert_eq!(task.id, "J1");
assert_eq!(task.name, "Job 1");
assert_eq!(task.category, "TypeA");
assert_eq!(task.priority, 10);
assert_eq!(task.deadline, Some(100_000));
assert_eq!(task.release_time, Some(0));
assert_eq!(task.attributes.get("customer"), Some(&"ACME".to_string()));
}
#[test]
fn test_task_total_duration() {
let task = Task::new("J1")
.with_activity(
Activity::new("O1", "J1", 0).with_duration(ActivityDuration::fixed(1000)),
)
.with_activity(
Activity::new("O2", "J1", 1).with_duration(ActivityDuration::fixed(2000)),
);
assert_eq!(task.total_duration_ms(), 3000);
assert_eq!(task.activity_count(), 2);
assert!(task.has_activities());
}
#[test]
fn test_task_empty() {
let task = Task::new("empty");
assert_eq!(task.total_duration_ms(), 0);
assert!(!task.has_activities());
}
}