use hitchmark_core::LinkStore;
use std::path::Path;
#[derive(clap::Parser)]
pub struct BookmarkArgs {
#[command(subcommand)]
pub command: BookmarkCmd,
}
#[derive(clap::Subcommand)]
pub enum BookmarkCmd {
Create {
path: String,
},
Show {
id: String,
},
Update {
id: String,
path: String,
},
List {
#[arg(long)]
json: bool,
},
}
pub fn execute(args: BookmarkArgs, store_path: &Path) -> anyhow::Result<()> {
let store = LinkStore::open(store_path)?;
match args.command {
BookmarkCmd::Create { path } => {
let canonical = std::fs::canonicalize(&path)
.map_err(|e| anyhow::anyhow!("Cannot resolve path '{path}': {e}"))?;
let path_str = canonical
.to_str()
.ok_or_else(|| anyhow::anyhow!("Path is not valid UTF-8"))?;
let id = store.store_bookmark(path_str)?;
println!("hook://bookmark/{id}");
}
BookmarkCmd::Show { id } => {
let id = strip_bookmark_prefix(&id);
match store.lookup_bookmark(id)? {
Some(path) => println!("{path}"),
None => anyhow::bail!("Bookmark '{id}' not found"),
}
}
BookmarkCmd::Update { id, path } => {
let id = strip_bookmark_prefix(&id).to_string();
let canonical = std::fs::canonicalize(&path)
.map_err(|e| anyhow::anyhow!("Cannot resolve path '{path}': {e}"))?;
let path_str = canonical
.to_str()
.ok_or_else(|| anyhow::anyhow!("Path is not valid UTF-8"))?;
if store.update_bookmark_path(&id, path_str)? {
println!("Updated bookmark {id} → {path_str}");
} else {
anyhow::bail!("Bookmark '{id}' not found");
}
}
BookmarkCmd::List { json } => {
let bookmarks = store.list_bookmarks()?;
if json {
println!("{}", serde_json::to_string_pretty(&bookmarks)?);
} else {
if bookmarks.is_empty() {
println!("No bookmarks stored.");
} else {
for b in &bookmarks {
println!("hook://bookmark/{}\t{}", b.id, b.file_path);
}
}
}
}
}
Ok(())
}
fn strip_bookmark_prefix(s: &str) -> &str {
s.strip_prefix("hook://bookmark/").unwrap_or(s)
}