todomd 0.3.0

A simple markdown-based todo list CLI and TUI - Added Kanban
Documentation
use crate::core::model::State;
use crate::core::store::Store;
use anyhow::Result;

pub struct DualStore<P: Store, S: Store> {
    primary: P,
    secondary: S,
}

impl<P: Store, S: Store> DualStore<P, S> {
    pub fn new(primary: P, secondary: S) -> Self {
        Self { primary, secondary }
    }
}

impl<P: Store, S: Store> Store for DualStore<P, S> {
    fn load(&self) -> Result<State> {
        // Normal path: load from primary (Markdown)
        let state = self.primary.load()?;
        
        // If primary is empty (either file missing or just no tasks), check secondary as fallback
        let is_empty = state.short.is_empty() && 
                       state.medium.is_empty() && 
                       state.long.is_empty() && 
                       state.completed.is_empty();
                       
        if is_empty {
            if let Ok(backup) = self.secondary.load() {
                // If backup has data, use it
                let backup_is_empty = backup.short.is_empty() && 
                                      backup.medium.is_empty() && 
                                      backup.long.is_empty() && 
                                      backup.completed.is_empty();
                if !backup_is_empty {
                    return Ok(backup);
                }
            }
        }
        
        Ok(state)
    }

    fn save(&self, state: &State) -> Result<()> {
        // Save to primary first (Markdown)
        self.primary.save(state)?;
        
        // Then save to secondary as backup (Trueno DB / Parquet)
        // We ignore errors in the backup for now or log them, 
        // to ensure the primary app remains functional even if backup fails.
        let _ = self.secondary.save(state);
        
        Ok(())
    }
}