use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use super::filter::TasksFilter;
use super::types::{Task, TaskId, TaskStatus};
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct TasksState {
pub(super) tasks: HashMap<TaskId, Task>,
}
impl TasksState {
pub fn new() -> Self {
Self::default()
}
pub fn get(&self, id: TaskId) -> Option<&Task> {
self.tasks.get(&id)
}
pub fn len(&self) -> usize {
self.tasks.len()
}
pub fn is_empty(&self) -> bool {
self.tasks.is_empty()
}
pub fn contains(&self, id: TaskId) -> bool {
self.tasks.contains_key(&id)
}
pub fn all(&self) -> impl Iterator<Item = &Task> {
self.tasks.values()
}
pub fn pending(&self) -> impl Iterator<Item = &Task> {
self.tasks
.values()
.filter(|t| t.status == TaskStatus::Pending)
}
pub fn completed(&self) -> impl Iterator<Item = &Task> {
self.tasks
.values()
.filter(|t| t.status == TaskStatus::Completed)
}
pub fn find_unique(&self, id: TaskId) -> Option<&Task> {
self.get(id)
}
pub fn find_many(&self, filter: &TasksFilter) -> Vec<Task> {
filter.apply(self.query()).collect()
}
pub fn count_where(&self, filter: &TasksFilter) -> usize {
filter.apply(self.query()).count()
}
pub fn exists_where(&self, filter: &TasksFilter) -> bool {
filter.apply(self.query()).exists()
}
}
#[cfg(test)]
mod tests {
use super::*;
fn task(id: TaskId, status: TaskStatus) -> Task {
Task {
id,
title: format!("task-{}", id),
status,
created_ns: 0,
updated_ns: 0,
}
}
#[test]
fn test_empty_state() {
let s = TasksState::new();
assert!(s.is_empty());
assert_eq!(s.len(), 0);
assert!(s.get(1).is_none());
assert!(!s.contains(1));
}
#[test]
fn test_queries_filter_by_status() {
let mut s = TasksState::new();
s.tasks.insert(1, task(1, TaskStatus::Pending));
s.tasks.insert(2, task(2, TaskStatus::Pending));
s.tasks.insert(3, task(3, TaskStatus::Completed));
assert_eq!(s.len(), 3);
assert_eq!(s.pending().count(), 2);
assert_eq!(s.completed().count(), 1);
assert_eq!(s.all().count(), 3);
assert!(s.contains(2));
assert!(!s.contains(99));
}
}