use crate::{ArchivedCard, Board, Card, Column, DependencyGraph, Sprint};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Snapshot {
#[serde(default)]
pub boards: Vec<Board>,
#[serde(default)]
pub columns: Vec<Column>,
#[serde(default)]
pub cards: Vec<Card>,
#[serde(default)]
pub archived_cards: Vec<ArchivedCard>,
#[serde(default)]
pub sprints: Vec<Sprint>,
#[serde(default)]
pub graph: DependencyGraph,
}
impl Snapshot {
pub fn new() -> Self {
Self::default()
}
pub fn from_data(
boards: Vec<Board>,
columns: Vec<Column>,
cards: Vec<Card>,
archived_cards: Vec<ArchivedCard>,
sprints: Vec<Sprint>,
graph: DependencyGraph,
) -> Self {
Self {
boards,
columns,
cards,
archived_cards,
sprints,
graph,
}
}
pub fn is_empty(&self) -> bool {
self.boards.is_empty()
&& self.columns.is_empty()
&& self.cards.is_empty()
&& self.archived_cards.is_empty()
&& self.sprints.is_empty()
}
pub fn to_json_bytes(&self) -> kanban_core::KanbanResult<Vec<u8>> {
let json = serde_json::to_vec_pretty(self)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
Ok(json)
}
pub fn from_json_bytes(bytes: &[u8]) -> kanban_core::KanbanResult<Snapshot> {
let snapshot = serde_json::from_slice(bytes)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
Ok(snapshot)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_empty_snapshot() {
let snapshot = Snapshot::new();
assert!(snapshot.is_empty());
assert!(snapshot.boards.is_empty());
assert!(snapshot.columns.is_empty());
assert!(snapshot.cards.is_empty());
}
#[test]
fn test_snapshot_from_data() {
let board = Board::new("Test".to_string(), None);
let snapshot = Snapshot::from_data(
vec![board.clone()],
vec![],
vec![],
vec![],
vec![],
DependencyGraph::new(),
);
assert!(!snapshot.is_empty());
assert_eq!(snapshot.boards.len(), 1);
assert_eq!(snapshot.boards[0].name, "Test");
}
#[test]
fn test_snapshot_serialization_roundtrip() {
let board = Board::new("Test Board".to_string(), None);
let snapshot = Snapshot::from_data(
vec![board],
vec![],
vec![],
vec![],
vec![],
DependencyGraph::new(),
);
let json = serde_json::to_string(&snapshot).unwrap();
let restored: Snapshot = serde_json::from_str(&json).unwrap();
assert_eq!(restored.boards.len(), 1);
assert_eq!(restored.boards[0].name, "Test Board");
assert!(restored.columns.is_empty());
}
#[test]
fn test_snapshot_partial_deserialization() {
let json = r#"{"boards": []}"#;
let snapshot: Snapshot = serde_json::from_str(json).unwrap();
assert!(snapshot.columns.is_empty());
assert!(snapshot.cards.is_empty());
assert!(snapshot.sprints.is_empty());
}
}