snipt-core 0.1.0

Core functionality for the Snipt application
Documentation
use crate::config::{ensure_config_dir, get_db_file_path};
use crate::error::{Result, SniptError};
use crate::models::SnippetEntry;
use std::fs;

/// Load all snippets from the database
pub fn load_snippets() -> Result<Vec<SnippetEntry>> {
    let path = get_db_file_path();
    if !path.exists() {
        return Err(SniptError::DatabaseNotFound(
            path.to_string_lossy().to_string(),
        ));
    }

    let content = fs::read_to_string(&path)?;

    // Handle empty database file
    if content.trim().is_empty() {
        return Ok(vec![]);
    }

    serde_json::from_str(&content).map_err(|e| e.into())
}

/// Save snippets to the database file
pub fn save_snippets(snippets: &[SnippetEntry]) -> Result<()> {
    let config_dir = ensure_config_dir()?;
    let db_path = config_dir.join("snipt.json");

    let serialized = serde_json::to_string_pretty(&snippets)?;
    fs::write(&db_path, serialized)?;

    Ok(())
}

/// Add a new snippet
pub fn add_snippet(shortcut: String, snippet: String) -> Result<()> {
    // Check for excessively large snippets
    if snippet.len() > 1_000_000 {
        // 1MB limit
        return Err(SniptError::Other(
            "Snippet is too large. Maximum size is 1MB.".to_string(),
        ));
    }

    let mut snippets = match load_snippets() {
        Ok(s) => s,
        Err(SniptError::DatabaseNotFound(_)) => vec![],
        Err(e) => return Err(e),
    };

    // Check for duplicate shortcut
    if snippets.iter().any(|entry| entry.shortcut == shortcut) {
        return Err(SniptError::Other(format!(
            "Shortcut '{}' already exists",
            shortcut
        )));
    }

    let entry = SnippetEntry::new(shortcut, snippet);
    snippets.push(entry);
    save_snippets(&snippets)
}

/// Delete a snippet by shortcut
pub fn delete_snippet(shortcut: &str) -> Result<()> {
    let mut snippets = load_snippets()?;
    snippets.retain(|entry| entry.shortcut != shortcut);
    save_snippets(&snippets)
}

/// Update an existing snippet
pub fn update_snippet(shortcut: &str, new_snippet: String) -> Result<()> {
    let mut snippets = load_snippets()?;
    let mut updated = false;

    for entry in &mut snippets {
        if entry.shortcut == shortcut {
            entry.update_snippet(new_snippet.clone());
            updated = true;
        }
    }

    if !updated {
        return Err(SniptError::Other(format!(
            "Shortcut '{}' not found",
            shortcut
        )));
    }

    save_snippets(&snippets)
}

/// Find a snippet by shortcut
pub fn find_snippet<'a>(snippets: &'a [SnippetEntry], shortcut: &str) -> Option<&'a SnippetEntry> {
    snippets.iter().find(|entry| entry.shortcut == shortcut)
}