bookyard 0.1.0

Build and locally edit a bookshelf for multiple mdBook projects.
use std::path::PathBuf;

use anyhow::Context;
use bookyard_core::{BookConfig, detect_book_source, insert_book, slugify_book_id};

pub fn run(
    source: PathBuf,
    folder: String,
    title: Option<String>,
    id: Option<String>,
    tags: Vec<String>,
) -> anyhow::Result<()> {
    let path = crate::commands::config_path()?;
    let root = crate::commands::root_dir()?;
    let mut config = crate::commands::load_config()?;
    let detected = detect_book_source(root.join(&source))
        .with_context(|| format!("failed to detect book source at {}", source.display()))?;
    let title = title.or(detected.title).unwrap_or_else(|| {
        source
            .file_name()
            .and_then(|p| p.to_str())
            .unwrap_or("Book")
            .to_owned()
    });
    let id = id.unwrap_or_else(|| slugify_book_id(&title));
    let next_order = config
        .books
        .iter()
        .map(|book| book.order)
        .max()
        .unwrap_or(0)
        + 10;
    let mut book = BookConfig::new_mdbook(
        id.clone(),
        title.clone(),
        source.to_string_lossy(),
        vec![folder],
    );
    book.tags = tags;
    book.order = next_order;
    insert_book(&mut config, book)?;
    config
        .save_to(&path)
        .with_context(|| format!("failed to write {}", path.display()))?;
    println!("added {id}: {title}");
    Ok(())
}