Update .gitignore, add CLI cheatsheet, and modify benchmark results

- Updated .gitignore to include new target files and reports.
- Added a new CLI cheatsheet document for quick reference on commands and flags.
- Modified benchmark results in `bench/dirty-vs-full.md` to reflect updated performance metrics.
- Changed permissions for `run_all_tests.sh` to make it executable.
- Updated `target/.rustc_info.json` with additional output information.
- Adjusted file modes for `target/release/marlin` and `target/release/marlin.d`.
This commit is contained in:
thePR0M3TH3AN committed 2025-05-20 14:59:02 -04:00
1 parent 121394cb4b
commit b43d3e3ebd
8 files changed
+33 -6

No files matched your search

+4
View File
@@ -48,3 +48,7 @@ saved_config.yaml
/target/
/cobertura.xml
/tarpaulin-report.html
target/.rustc_info.json
target/release/marlin
target/release/marlin.d
tarpaulin-report.html
+2 -2
View File
@@ -1,4 +1,4 @@
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|:---|---:|---:|---:|---:|
| `full-scan` | 504.7 ± 38.5 | 462.3 | 562.2 | 6.75 ± 0.67 |
| `dirty-scan` | 74.8 ± 4.8 | 66.9 | 81.3 | 1.00 |
| `full-scan` | 631.7 ± 78.1 | 541.8 | 711.3 | 8.72 ± 1.39 |
| `dirty-scan` | 72.5 ± 7.3 | 63.2 | 85.7 | 1.00 |
+23
View File
@@ -0,0 +1,23 @@
| Command | Flags |
| ------- | ----- |
| `link add` | --type |
| `link rm` | --type |
| `link list` | --direction, --type |
| `link backlinks` | — |
| `coll create` | — |
| `coll add` | — |
| `coll list` | — |
| `view save` | — |
| `view list` | — |
| `view exec` | — |
| `state set` | — |
| `state transitions-add` | — |
| `state log` | — |
| `task scan` | — |
| `task list` | --due-today |
| `remind set` | — |
| `annotate add` | --range, --highlight |
| `annotate list` | — |
| `version diff` | — |
| `event add` | — |
| `event timeline` | — |
Regular → Executable
View File
File mode changed.
+1 -1
View File
@@ -1 +1 @@
{"rustc_fingerprint":490527502257410439,"outputs":{"17747080675513052775":{"success":true,"status":"","code":0,"stdout":"rustc 1.87.0 (17067e9ac 2025-05-09)\nbinary: rustc\ncommit-hash: 17067e9ac6d7ecb70e50f92c1944e545188d2359\ncommit-date: 2025-05-09\nhost: x86_64-unknown-linux-gnu\nrelease: 1.87.0\nLLVM version: 20.1.1\n","stderr":""}},"successes":{}}
{"rustc_fingerprint":490527502257410439,"outputs":{"17747080675513052775":{"success":true,"status":"","code":0,"stdout":"rustc 1.87.0 (17067e9ac 2025-05-09)\nbinary: rustc\ncommit-hash: 17067e9ac6d7ecb70e50f92c1944e545188d2359\ncommit-date: 2025-05-09\nhost: x86_64-unknown-linux-gnu\nrelease: 1.87.0\nLLVM version: 20.1.1\n","stderr":""},"7971740275564407648":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/user/.rustup/toolchains/stable-x86_64-unknown-linux-gnu\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""},"10431901537437931773":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/user/.rustup/toolchains/stable-x86_64-unknown-linux-gnu\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\ntarpaulin\nunix\n","stderr":""}},"successes":{}}
Regular → Executable
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
/workspace/Marlin/target/release/marlin: /workspace/Marlin/cli-bin/build.rs /workspace/Marlin/cli-bin/src/cli/annotate.rs /workspace/Marlin/cli-bin/src/cli/coll.rs /workspace/Marlin/cli-bin/src/cli/event.rs /workspace/Marlin/cli-bin/src/cli/link.rs /workspace/Marlin/cli-bin/src/cli/remind.rs /workspace/Marlin/cli-bin/src/cli/state.rs /workspace/Marlin/cli-bin/src/cli/task.rs /workspace/Marlin/cli-bin/src/cli/version.rs /workspace/Marlin/cli-bin/src/cli/view.rs /workspace/Marlin/cli-bin/src/cli/watch.rs /workspace/Marlin/cli-bin/src/cli.rs /workspace/Marlin/cli-bin/src/main.rs /workspace/Marlin/libmarlin/src/backup.rs /workspace/Marlin/libmarlin/src/config.rs /workspace/Marlin/libmarlin/src/db/database.rs /workspace/Marlin/libmarlin/src/db/migrations/0001_initial_schema.sql /workspace/Marlin/libmarlin/src/db/migrations/0002_update_fts_and_triggers.sql /workspace/Marlin/libmarlin/src/db/migrations/0003_create_links_collections_views.sql /workspace/Marlin/libmarlin/src/db/migrations/0004_fix_hierarchical_tags_fts.sql /workspace/Marlin/libmarlin/src/db/migrations/0005_add_dirty_table.sql /workspace/Marlin/libmarlin/src/db/mod.rs /workspace/Marlin/libmarlin/src/error.rs /workspace/Marlin/libmarlin/src/lib.rs /workspace/Marlin/libmarlin/src/logging.rs /workspace/Marlin/libmarlin/src/scan.rs /workspace/Marlin/libmarlin/src/utils.rs /workspace/Marlin/libmarlin/src/watcher.rs
/home/user/Documents/GitHub/Marlin/target/release/marlin: /home/user/Documents/GitHub/Marlin/cli-bin/build.rs /home/user/Documents/GitHub/Marlin/cli-bin/src/cli/annotate.rs /home/user/Documents/GitHub/Marlin/cli-bin/src/cli/coll.rs /home/user/Documents/GitHub/Marlin/cli-bin/src/cli/commands.yaml /home/user/Documents/GitHub/Marlin/cli-bin/src/cli/event.rs /home/user/Documents/GitHub/Marlin/cli-bin/src/cli/link.rs /home/user/Documents/GitHub/Marlin/cli-bin/src/cli/remind.rs /home/user/Documents/GitHub/Marlin/cli-bin/src/cli/state.rs /home/user/Documents/GitHub/Marlin/cli-bin/src/cli/task.rs /home/user/Documents/GitHub/Marlin/cli-bin/src/cli/version.rs /home/user/Documents/GitHub/Marlin/cli-bin/src/cli/view.rs /home/user/Documents/GitHub/Marlin/cli-bin/src/cli/watch.rs /home/user/Documents/GitHub/Marlin/cli-bin/src/cli.rs /home/user/Documents/GitHub/Marlin/cli-bin/src/main.rs /home/user/Documents/GitHub/Marlin/libmarlin/src/backup.rs /home/user/Documents/GitHub/Marlin/libmarlin/src/config.rs /home/user/Documents/GitHub/Marlin/libmarlin/src/db/database.rs /home/user/Documents/GitHub/Marlin/libmarlin/src/db/migrations/0001_initial_schema.sql /home/user/Documents/GitHub/Marlin/libmarlin/src/db/migrations/0002_update_fts_and_triggers.sql /home/user/Documents/GitHub/Marlin/libmarlin/src/db/migrations/0003_create_links_collections_views.sql /home/user/Documents/GitHub/Marlin/libmarlin/src/db/migrations/0004_fix_hierarchical_tags_fts.sql /home/user/Documents/GitHub/Marlin/libmarlin/src/db/migrations/0005_add_dirty_table.sql /home/user/Documents/GitHub/Marlin/libmarlin/src/db/mod.rs /home/user/Documents/GitHub/Marlin/libmarlin/src/error.rs /home/user/Documents/GitHub/Marlin/libmarlin/src/lib.rs /home/user/Documents/GitHub/Marlin/libmarlin/src/logging.rs /home/user/Documents/GitHub/Marlin/libmarlin/src/scan.rs /home/user/Documents/GitHub/Marlin/libmarlin/src/utils.rs /home/user/Documents/GitHub/Marlin/libmarlin/src/watcher.rs
+2 -2
View File
@@ -118,8 +118,8 @@
<body>
<div id="root"></div>
<script>
var data = {"files":[{"path":["/","home","user","Documents","GitHub","Marlin","cli-bin","build.rs"],"content":"// cli-bin/build.rs\n//\n// The CLI currently needs no build-time code-generation, but Cargo\n// insists on rerunning any build-script each compile. Tell it to\n// rebuild only if this file itself changes.\n\nfn main() {\n // If you later add code-gen (e.g. embed completions or YAML), add\n // further `cargo:rerun-if-changed=\u003cpath\u003e` lines here.\n println!(\"cargo:rerun-if-changed=build.rs\");\n}\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","user","Documents","GitHub","Marlin","cli-bin","src","cli","annotate.rs"],"content":"// src/cli/annotate.rs\nuse clap::{Subcommand, Args};\nuse rusqlite::Connection;\nuse crate::cli::Format;\n\n#[derive(Subcommand, Debug)]\npub enum AnnotateCmd {\n Add (ArgsAdd),\n List(ArgsList),\n}\n\n#[derive(Args, Debug)]\npub struct ArgsAdd {\n pub file: String,\n pub note: String,\n #[arg(long)] pub range: Option\u003cString\u003e,\n #[arg(long)] pub highlight: bool,\n}\n\n#[derive(Args, Debug)]\npub struct ArgsList { pub file_pattern: String }\n\npub fn run(cmd: \u0026AnnotateCmd, _conn: \u0026mut Connection, _format: Format) -\u003e anyhow::Result\u003c()\u003e {\n match cmd {\n AnnotateCmd::Add(a) =\u003e todo!(\"annotate add {:?}\", a),\n AnnotateCmd::List(a) =\u003e todo!(\"annotate list {:?}\", a),\n }\n}\n","traces":[{"line":23,"address":[2450848],"length":1,"stats":{"Line":0}},{"line":24,"address":[2450887],"length":1,"stats":{"Line":0}}],"covered":0,"coverable":2},{"path":["/","home","user","Documents","GitHub","Marlin","cli-bin","src","cli","coll.rs"],"content":"//! `marlin coll …` – named collections of files (simple “playlists”).\n\nuse clap::{Args, Subcommand};\nuse rusqlite::Connection;\n\nuse crate::cli::Format; // local enum for text / json output\nuse libmarlin::db; // core DB helpers from the library crate\n\n#[derive(Subcommand, Debug)]\npub enum CollCmd {\n /// Create an empty collection\n Create(CreateArgs),\n /// Add files (glob) to a collection\n Add(AddArgs),\n /// List files inside a collection\n List(ListArgs),\n}\n\n#[derive(Args, Debug)]\npub struct CreateArgs {\n pub name: String,\n}\n\n#[derive(Args, Debug)]\npub struct AddArgs {\n pub name: String,\n pub file_pattern: String,\n}\n\n#[derive(Args, Debug)]\npub struct ListArgs {\n pub name: String,\n}\n\n/// Look-up an existing collection **without** implicitly creating it.\n///\n/// Returns the collection ID or an error if it doesn’t exist.\nfn lookup_collection_id(conn: \u0026Connection, name: \u0026str) -\u003e anyhow::Result\u003ci64\u003e {\n conn.query_row(\n \"SELECT id FROM collections WHERE name = ?1\",\n [name],\n |r| r.get(0),\n )\n .map_err(|_| anyhow::anyhow!(\"collection not found: {}\", name))\n}\n\npub fn run(cmd: \u0026CollCmd, conn: \u0026mut Connection, fmt: Format) -\u003e anyhow::Result\u003c()\u003e {\n match cmd {\n /* ── coll create ──────────────────────────────────────────── */\n CollCmd::Create(a) =\u003e {\n db::ensure_collection(conn, \u0026a.name)?;\n if matches!(fmt, Format::Text) {\n println!(\"Created collection '{}'\", a.name);\n }\n }\n\n /* ── coll add ─────────────────────────────────────────────── */\n CollCmd::Add(a) =\u003e {\n // Fail if the target collection does not yet exist\n let coll_id = lookup_collection_id(conn, \u0026a.name)?;\n\n let like = a.file_pattern.replace('*', \"%\");\n let mut stmt = conn.prepare(\"SELECT id FROM files WHERE path LIKE ?1\")?;\n let ids: Vec\u003ci64\u003e = stmt\n .query_map([\u0026like], |r| r.get::\u003c_, i64\u003e(0))?\n .collect::\u003cResult\u003c_, _\u003e\u003e()?;\n\n for fid in \u0026ids {\n db::add_file_to_collection(conn, coll_id, *fid)?;\n }\n\n match fmt {\n Format::Text =\u003e println!(\"Added {} file(s) → '{}'\", ids.len(), a.name),\n Format::Json =\u003e {\n #[cfg(feature = \"json\")]\n {\n println!(\n \"{{\\\"collection\\\":\\\"{}\\\",\\\"added\\\":{}}}\",\n a.name,\n ids.len()\n );\n }\n }\n }\n }\n\n /* ── coll list ────────────────────────────────────────────── */\n CollCmd::List(a) =Line truncated
var previousData = {"files":[{"path":["/","home","user","Documents","GitHub","Marlin","cli-bin","build.rs"],"content":"// cli-bin/build.rs\n//\n// The CLI currently needs no build-time code-generation, but Cargo\n// insists on rerunning any build-script each compile. Tell it to\n// rebuild only if this file itself changes.\n\nfn main() {\n // If you later add code-gen (e.g. embed completions or YAML), add\n // further `cargo:rerun-if-changed=\u003cpath\u003e` lines here.\n println!(\"cargo:rerun-if-changed=build.rs\");\n}\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","user","Documents","GitHub","Marlin","cli-bin","src","cli","annotate.rs"],"content":"// src/cli/annotate.rs\nuse clap::{Subcommand, Args};\nuse rusqlite::Connection;\nuse crate::cli::Format;\n\n#[derive(Subcommand, Debug)]\npub enum AnnotateCmd {\n Add (ArgsAdd),\n List(ArgsList),\n}\n\n#[derive(Args, Debug)]\npub struct ArgsAdd {\n pub file: String,\n pub note: String,\n #[arg(long)] pub range: Option\u003cString\u003e,\n #[arg(long)] pub highlight: bool,\n}\n\n#[derive(Args, Debug)]\npub struct ArgsList { pub file_pattern: String }\n\npub fn run(cmd: \u0026AnnotateCmd, _conn: \u0026mut Connection, _format: Format) -\u003e anyhow::Result\u003c()\u003e {\n match cmd {\n AnnotateCmd::Add(a) =\u003e todo!(\"annotate add {:?}\", a),\n AnnotateCmd::List(a) =\u003e todo!(\"annotate list {:?}\", a),\n }\n}\n","traces":[{"line":23,"address":[2450848],"length":1,"stats":{"Line":0}},{"line":24,"address":[2450887],"length":1,"stats":{"Line":0}}],"covered":0,"coverable":2},{"path":["/","home","user","Documents","GitHub","Marlin","cli-bin","src","cli","coll.rs"],"content":"//! `marlin coll …` – named collections of files (simple “playlists”).\n\nuse clap::{Args, Subcommand};\nuse rusqlite::Connection;\n\nuse crate::cli::Format; // local enum for text / json output\nuse libmarlin::db; // core DB helpers from the library crate\n\n#[derive(Subcommand, Debug)]\npub enum CollCmd {\n /// Create an empty collection\n Create(CreateArgs),\n /// Add files (glob) to a collection\n Add(AddArgs),\n /// List files inside a collection\n List(ListArgs),\n}\n\n#[derive(Args, Debug)]\npub struct CreateArgs {\n pub name: String,\n}\n\n#[derive(Args, Debug)]\npub struct AddArgs {\n pub name: String,\n pub file_pattern: String,\n}\n\n#[derive(Args, Debug)]\npub struct ListArgs {\n pub name: String,\n}\n\n/// Look-up an existing collection **without** implicitly creating it.\n///\n/// Returns the collection ID or an error if it doesn’t exist.\nfn lookup_collection_id(conn: \u0026Connection, name: \u0026str) -\u003e anyhow::Result\u003ci64\u003e {\n conn.query_row(\n \"SELECT id FROM collections WHERE name = ?1\",\n [name],\n |r| r.get(0),\n )\n .map_err(|_| anyhow::anyhow!(\"collection not found: {}\", name))\n}\n\npub fn run(cmd: \u0026CollCmd, conn: \u0026mut Connection, fmt: Format) -\u003e anyhow::Result\u003c()\u003e {\n match cmd {\n /* ── coll create ──────────────────────────────────────────── */\n CollCmd::Create(a) =\u003e {\n db::ensure_collection(conn, \u0026a.name)?;\n if matches!(fmt, Format::Text) {\n println!(\"Created collection '{}'\", a.name);\n }\n }\n\n /* ── coll add ─────────────────────────────────────────────── */\n CollCmd::Add(a) =\u003e {\n // Fail if the target collection does not yet exist\n let coll_id = lookup_collection_id(conn, \u0026a.name)?;\n\n let like = a.file_pattern.replace('*', \"%\");\n let mut stmt = conn.prepare(\"SELECT id FROM files WHERE path LIKE ?1\")?;\n let ids: Vec\u003ci64\u003e = stmt\n .query_map([\u0026like], |r| r.get::\u003c_, i64\u003e(0))?\n .collect::\u003cResult\u003c_, _\u003e\u003e()?;\n\n for fid in \u0026ids {\n db::add_file_to_collection(conn, coll_id, *fid)?;\n }\n\n match fmt {\n Format::Text =\u003e println!(\"Added {} file(s) → '{}'\", ids.len(), a.name),\n Format::Json =\u003e {\n #[cfg(feature = \"json\")]\n {\n println!(\n \"{{\\\"collection\\\":\\\"{}\\\",\\\"added\\\":{}}}\",\n a.name,\n ids.len()\n );\n }\n }\n }\n }\n\n /* ── coll list ────────────────────────────────────────────── */\n CollCmd::LLine truncated
var data = {"files":[{"path":["/","home","user","Documents","GitHub","Marlin","cli-bin","build.rs"],"content":"// cli-bin/build.rs\n//\n// Build script to generate the CLI cheatsheet at compile time. It\n// parses `src/cli/commands.yaml` and emits a simple Markdown table of\n// commands and flags to `docs/cli_cheatsheet.md`.\n\nuse std::{fs, path::Path};\n\nuse serde_yaml::Value;\n\nfn main() {\n println!(\"cargo:rerun-if-changed=build.rs\");\n println!(\"cargo:rerun-if-changed=src/cli/commands.yaml\");\n\n if let Err(e) = generate_cheatsheet() {\n eprintln!(\"Failed to generate CLI cheatsheet: {e}\");\n std::process::exit(1);\n }\n}\n\nfn generate_cheatsheet() -\u003e Result\u003c(), Box\u003cdyn std::error::Error\u003e\u003e {\n let yaml_str = fs::read_to_string(\"src/cli/commands.yaml\")?;\n let parsed: Value = serde_yaml::from_str(\u0026yaml_str)?;\n\n let mut table = String::from(\"| Command | Flags |\\n| ------- | ----- |\\n\");\n\n if let Value::Mapping(cmds) = parsed {\n for (cmd_name_val, cmd_details_val) in cmds {\n let cmd_name = cmd_name_val.as_str().unwrap_or(\"\");\n if let Value::Mapping(cmd_details) = cmd_details_val {\n if let Some(Value::Mapping(actions)) = cmd_details.get(\u0026Value::String(\"actions\".into())) {\n for (action_name_val, action_body_val) in actions {\n let action_name = action_name_val.as_str().unwrap_or(\"\");\n let flags = if let Value::Mapping(action_map) = action_body_val {\n match action_map.get(\u0026Value::String(\"flags\".into())) {\n Some(Value::Sequence(seq)) =\u003e seq\n .iter()\n .filter_map(|v| v.as_str())\n .collect::\u003cVec\u003c_\u003e\u003e()\n .join(\", \"),\n _ =\u003e String::new(),\n }\n } else {\n String::new()\n };\n\n let flags_disp = if flags.is_empty() { \"—\" } else { \u0026flags };\n table.push_str(\u0026format!(\"| `{}` | {} |\\n\", format!(\"{} {}\", cmd_name, action_name), flags_disp));\n }\n }\n }\n }\n }\n\n fs::create_dir_all(Path::new(\"docs\"))?;\n fs::write(\"docs/cli_cheatsheet.md\", table)?;\n\n Ok(())\n}\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","user","Documents","GitHub","Marlin","cli-bin","src","cli","annotate.rs"],"content":"// src/cli/annotate.rs\nuse clap::{Subcommand, Args};\nuse rusqlite::Connection;\nuse crate::cli::Format;\n\n#[derive(Subcommand, Debug)]\npub enum AnnotateCmd {\n Add (ArgsAdd),\n List(ArgsList),\n}\n\n#[derive(Args, Debug)]\npub struct ArgsAdd {\n pub file: String,\n pub note: String,\n #[arg(long)] pub range: Option\u003cString\u003e,\n #[arg(long)] pub highlight: bool,\n}\n\n#[derive(Args, Debug)]\npub struct ArgsList { pub file_pattern: String }\n\npub fn run(cmd: \u0026AnnotateCmd, _conn: \u0026mut Connection, _format: Format) -\u003e anyhow::Result\u003c()\u003e {\n match cmd {\n AnnotateCmd::Add(a) =\u003e todo!(\"annotate add {:?}\", a),\n AnnotateCmd::List(a) =\u003e todo!(\"annotate list {:?}\", a),\n }\n}\n","traces":[{"line":23,"address":[2405584],"length":1,"stats":{"Line":0}},{"line":24,"address":[2405623],"length":1,"stats":{"Line":0}}],"covered":0,"coverable":2},{"path":["/","home","user","Documents","GitHub","Marlin","cli-bin","src","cli","coll.rs"],"content":"//! `marlin coll …` – named collections of files (simple “playlists”).\n\nuse clap::{Args, Subcommand};\nuse rusqlite::Connection;\n\nuse crate::cli::Format; // local enum for text / json output\nuse libmarlin::db; // core DB helpers from the library crate\n\n#[derive(Subcommand, Debug)]\npub enum CollCmd {\n /// Create an empty collection\n Create(CreateArgs),\n /// Add files (glob) to a collection\n Add(AddArgs),\n /// List files inside a collection\n List(ListArgs),\n}\n\n#[derive(Args, Debug)]\npub struct CreateArgs {\n pub name: String,\n}\n\n#[derive(Args, Debug)]\npub struct AddArgs {\n pub name: String,\n pub file_pattern: String,\n}\n\n#[derive(Args, Debug)]\npub struct ListArgs {\n pub name: String,\n}\n\n/// Look-up an existing collection **without** implicitly creating it.\n///\n/// Returns the collection ID or an error if it doesn’t exist.\nfn lookup_collection_id(conn: \u0026Connection, name: \u0026str) -\u003e anyhow::Result\u003ci64\u003e {\n conn.query_row(\n \"SELECT id FROM collections WHERE name = ?1\",\n [name],\n |r| r.get(0),\n )\n .map_err(|_| anyhow::anyhow!(\"collection not found: {}\Line truncated
var previousData = {"files":[{"path":["/","home","user","Documents","GitHub","Marlin","cli-bin","build.rs"],"content":"// cli-bin/build.rs\n//\n// Build script to generate the CLI cheatsheet at compile time. It\n// parses `src/cli/commands.yaml` and emits a simple Markdown table of\n// commands and flags to `docs/cli_cheatsheet.md`.\n\nuse std::{fs, path::Path};\n\nuse serde_yaml::Value;\n\nfn main() {\n println!(\"cargo:rerun-if-changed=build.rs\");\n println!(\"cargo:rerun-if-changed=src/cli/commands.yaml\");\n\n if let Err(e) = generate_cheatsheet() {\n eprintln!(\"Failed to generate CLI cheatsheet: {e}\");\n std::process::exit(1);\n }\n}\n\nfn generate_cheatsheet() -\u003e Result\u003c(), Box\u003cdyn std::error::Error\u003e\u003e {\n let yaml_str = fs::read_to_string(\"src/cli/commands.yaml\")?;\n let parsed: Value = serde_yaml::from_str(\u0026yaml_str)?;\n\n let mut table = String::from(\"| Command | Flags |\\n| ------- | ----- |\\n\");\n\n if let Value::Mapping(cmds) = parsed {\n for (cmd_name_val, cmd_details_val) in cmds {\n let cmd_name = cmd_name_val.as_str().unwrap_or(\"\");\n if let Value::Mapping(cmd_details) = cmd_details_val {\n if let Some(Value::Mapping(actions)) = cmd_details.get(\u0026Value::String(\"actions\".into())) {\n for (action_name_val, action_body_val) in actions {\n let action_name = action_name_val.as_str().unwrap_or(\"\");\n let flags = if let Value::Mapping(action_map) = action_body_val {\n match action_map.get(\u0026Value::String(\"flags\".into())) {\n Some(Value::Sequence(seq)) =\u003e seq\n .iter()\n .filter_map(|v| v.as_str())\n .collect::\u003cVec\u003c_\u003e\u003e()\n .join(\", \"),\n _ =\u003e String::new(),\n }\n } else {\n String::new()\n };\n\n let flags_disp = if flags.is_empty() { \"—\" } else { \u0026flags };\n table.push_str(\u0026format!(\"| `{}` | {} |\\n\", format!(\"{} {}\", cmd_name, action_name), flags_disp));\n }\n }\n }\n }\n }\n\n fs::create_dir_all(Path::new(\"docs\"))?;\n fs::write(\"docs/cli_cheatsheet.md\", table)?;\n\n Ok(())\n}\n","traces":[],"covered":0,"coverable":0},{"path":["/","home","user","Documents","GitHub","Marlin","cli-bin","src","cli","annotate.rs"],"content":"// src/cli/annotate.rs\nuse clap::{Subcommand, Args};\nuse rusqlite::Connection;\nuse crate::cli::Format;\n\n#[derive(Subcommand, Debug)]\npub enum AnnotateCmd {\n Add (ArgsAdd),\n List(ArgsList),\n}\n\n#[derive(Args, Debug)]\npub struct ArgsAdd {\n pub file: String,\n pub note: String,\n #[arg(long)] pub range: Option\u003cString\u003e,\n #[arg(long)] pub highlight: bool,\n}\n\n#[derive(Args, Debug)]\npub struct ArgsList { pub file_pattern: String }\n\npub fn run(cmd: \u0026AnnotateCmd, _conn: \u0026mut Connection, _format: Format) -\u003e anyhow::Result\u003c()\u003e {\n match cmd {\n AnnotateCmd::Add(a) =\u003e todo!(\"annotate add {:?}\", a),\n AnnotateCmd::List(a) =\u003e todo!(\"annotate list {:?}\", a),\n }\n}\n","traces":[{"line":23,"address":[2450848],"length":1,"stats":{"Line":0}},{"line":24,"address":[2450887],"length":1,"stats":{"Line":0}}],"covered":0,"coverable":2},{"path":["/","home","user","Documents","GitHub","Marlin","cli-bin","src","cli","coll.rs"],"content":"//! `marlin coll …` – named collections of files (simple “playlists”).\n\nuse clap::{Args, Subcommand};\nuse rusqlite::Connection;\n\nuse crate::cli::Format; // local enum for text / json output\nuse libmarlin::db; // core DB helpers from the library crate\n\n#[derive(Subcommand, Debug)]\npub enum CollCmd {\n /// Create an empty collection\n Create(CreateArgs),\n /// Add files (glob) to a collection\n Add(AddArgs),\n /// List files inside a collection\n List(ListArgs),\n}\n\n#[derive(Args, Debug)]\npub struct CreateArgs {\n pub name: String,\n}\n\n#[derive(Args, Debug)]\npub struct AddArgs {\n pub name: String,\n pub file_pattern: String,\n}\n\n#[derive(Args, Debug)]\npub struct ListArgs {\n pub name: String,\n}\n\n/// Look-up an existing collection **without** implicitly creating it.\n///\n/// Returns the collection ID or an error if it doesn’t exist.\nfn lookup_collection_id(conn: \u0026Connection, name: \u0026str) -\u003e anyhow::Result\u003ci64\u003e {\n conn.query_row(\n \"SELECT id FROM collections WHERE name = ?1\",\n [name],\n |r| r.get(0),\n )\n .map_err(|_| anyhow::anyhow!(\"collection not foLine truncated
</script>
<script crossorigin>/** @license React v16.13.1
* react.production.min.js