From e1f51dc06c4dda19d3bd102a5ccecf4a5e27b7d6 Mon Sep 17 00:00:00 2001 From: "heesk0223@gmail.com" Date: Thu, 4 Jun 2026 00:12:28 +0900 Subject: [PATCH] Add Cli CRUD feature --- .vault/src/main.rs.yml | 10 + Cargo.lock | 201 +++++++++++++++--- Cargo.toml | 5 +- apps/frilvault-cli/Cargo.toml | 12 ++ apps/frilvault-cli/src/cli/add.rs | 16 ++ apps/frilvault-cli/src/cli/delete.rs | 10 + apps/frilvault-cli/src/cli/list.rs | 7 + apps/frilvault-cli/src/cli/mod.rs | 30 +++ apps/frilvault-cli/src/cli/update.rs | 13 ++ apps/frilvault-cli/src/command/add.rs | 24 +++ apps/frilvault-cli/src/command/delete.rs | 14 ++ apps/frilvault-cli/src/command/list.rs | 23 ++ apps/frilvault-cli/src/command/mod.rs | 18 ++ apps/frilvault-cli/src/command/update.rs | 18 ++ apps/frilvault-cli/src/main.rs | 30 +++ apps/frivault-cli/Cargo.toml | 6 - apps/frivault-cli/src/main.rs | 3 - crates/frilvault-core/Cargo.toml | 2 +- crates/frilvault-core/src/lib.rs | 2 +- crates/frilvault-core/src/note/service.rs | 49 ++++- .../src/storage/yaml_repository.rs | 6 + .../src/tests/note_service_test.rs | 70 ++++++ 22 files changed, 520 insertions(+), 49 deletions(-) create mode 100644 .vault/src/main.rs.yml create mode 100644 apps/frilvault-cli/Cargo.toml create mode 100644 apps/frilvault-cli/src/cli/add.rs create mode 100644 apps/frilvault-cli/src/cli/delete.rs create mode 100644 apps/frilvault-cli/src/cli/list.rs create mode 100644 apps/frilvault-cli/src/cli/mod.rs create mode 100644 apps/frilvault-cli/src/cli/update.rs create mode 100644 apps/frilvault-cli/src/command/add.rs create mode 100644 apps/frilvault-cli/src/command/delete.rs create mode 100644 apps/frilvault-cli/src/command/list.rs create mode 100644 apps/frilvault-cli/src/command/mod.rs create mode 100644 apps/frilvault-cli/src/command/update.rs create mode 100644 apps/frilvault-cli/src/main.rs delete mode 100644 apps/frivault-cli/Cargo.toml delete mode 100644 apps/frivault-cli/src/main.rs diff --git a/.vault/src/main.rs.yml b/.vault/src/main.rs.yml new file mode 100644 index 0000000..c91a7fe --- /dev/null +++ b/.vault/src/main.rs.yml @@ -0,0 +1,10 @@ +notes: + - id: "4c019c16-fbed-4374-99a4-7b508c1f801e" + source_file: src/main.rs + anchor: + type: Line + line: 10 + column: 5 + content: new content + created_at: "2026-06-03T15:06:39.025847Z" + updated_at: "2026-06-03T15:09:37.992766Z" \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 97b35dd..8fc3293 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,56 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "anstyle-parse" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys", +] + [[package]] name = "anyhow" version = "1.0.102" @@ -65,6 +115,52 @@ dependencies = [ "windows-link", ] +[[package]] +name = "clap" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + +[[package]] +name = "colorchoice" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -89,6 +185,16 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "frilvault-cli" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "frilvault-core", + "uuid", +] + [[package]] name = "frilvault-core" version = "0.1.0" @@ -100,10 +206,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "frivault-cli" -version = "0.1.0" - [[package]] name = "futures-core" version = "0.3.32" @@ -204,6 +306,12 @@ dependencies = [ "serde_core", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + [[package]] name = "itoa" version = "1.0.18" @@ -234,16 +342,6 @@ version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" -[[package]] -name = "libyml" -version = "0.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3302702afa434ffa30847a83305f0a69d6abd74293b6554c18ec85c7ef30c980" -dependencies = [ - "anyhow", - "version_check", -] - [[package]] name = "log" version = "0.4.31" @@ -256,6 +354,19 @@ version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" +[[package]] +name = "noyalib" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e493c05128df7a83b9676b709d590e0ebc285c7ed3152bc679668e8c1e506af5" +dependencies = [ + "indexmap", + "memchr", + "rustc-hash", + "serde", + "smallvec", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -271,6 +382,12 @@ version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + [[package]] name = "pin-project-lite" version = "0.2.17" @@ -312,16 +429,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] -name = "rustversion" -version = "1.0.22" +name = "rustc-hash" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" [[package]] -name = "ryu" -version = "1.0.23" +name = "rustversion" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "semver" @@ -374,17 +491,12 @@ dependencies = [ [[package]] name = "serde_yml" -version = "0.0.12" +version = "0.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59e2dd588bf1597a252c3b920e0143eb99b0f76e4e082f4c92ce34fbc9e71ddd" +checksum = "909764a65f86829ccdb5eea9ab355843aa02c019a7bfd47465092953565caa05" dependencies = [ - "indexmap", - "itoa", - "libyml", - "memchr", - "ryu", + "noyalib", "serde", - "version_check", ] [[package]] @@ -399,6 +511,18 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "syn" version = "2.0.117" @@ -442,6 +566,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "uuid" version = "1.23.2" @@ -454,12 +584,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - [[package]] name = "wasip2" version = "1.0.3+wasi-0.2.9" @@ -616,6 +740,15 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + [[package]] name = "wit-bindgen" version = "0.51.0" diff --git a/Cargo.toml b/Cargo.toml index 41c6fba..da2d1fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] resolver = "2" -members = ["apps/frivault-cli", - "crates/frilvault-core" +members = [ + "apps/frilvault-cli", + "crates/frilvault-core", ] diff --git a/apps/frilvault-cli/Cargo.toml b/apps/frilvault-cli/Cargo.toml new file mode 100644 index 0000000..5139d8e --- /dev/null +++ b/apps/frilvault-cli/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "frilvault-cli" +version = "0.1.0" +edition = "2024" + +[dependencies] +clap = { version = "4", features = ["derive"] } +anyhow = "1" +uuid = { version = "1", features = ["v4", "serde"] } + + +frilvault-core = { path = "../../crates/frilvault-core" } \ No newline at end of file diff --git a/apps/frilvault-cli/src/cli/add.rs b/apps/frilvault-cli/src/cli/add.rs new file mode 100644 index 0000000..522006a --- /dev/null +++ b/apps/frilvault-cli/src/cli/add.rs @@ -0,0 +1,16 @@ +use clap::Args; + +#[derive(Debug, Args)] +pub struct AddCommand { + #[arg(long)] + pub file: String, + + #[arg(long)] + pub line: u32, + + #[arg(long)] + pub column: u32, + + #[arg(long)] + pub content: String, +} diff --git a/apps/frilvault-cli/src/cli/delete.rs b/apps/frilvault-cli/src/cli/delete.rs new file mode 100644 index 0000000..8467299 --- /dev/null +++ b/apps/frilvault-cli/src/cli/delete.rs @@ -0,0 +1,10 @@ +use clap::Args; + +#[derive(Debug, Args)] +pub struct DeleteCommand { + #[arg(long)] + pub file: String, + + #[arg(long)] + pub id: String, +} diff --git a/apps/frilvault-cli/src/cli/list.rs b/apps/frilvault-cli/src/cli/list.rs new file mode 100644 index 0000000..3c694c9 --- /dev/null +++ b/apps/frilvault-cli/src/cli/list.rs @@ -0,0 +1,7 @@ +use clap::Args; + +#[derive(Debug, Args)] +pub struct ListCommand { + #[arg(long)] + pub file: String, +} diff --git a/apps/frilvault-cli/src/cli/mod.rs b/apps/frilvault-cli/src/cli/mod.rs new file mode 100644 index 0000000..e0c9e30 --- /dev/null +++ b/apps/frilvault-cli/src/cli/mod.rs @@ -0,0 +1,30 @@ +use clap::{Parser, Subcommand}; + +pub mod add; +pub mod delete; +pub mod list; +pub mod update; + +use add::AddCommand; +use delete::DeleteCommand; +use list::ListCommand; +use update::UpdateCommand; + +#[derive(Parser)] +#[command( + name = "frilvault", + version, + about = "Personal note vault for source code" +)] +pub struct Cli { + #[command(subcommand)] + pub command: Commands, +} + +#[derive(Subcommand)] +pub enum Commands { + Add(AddCommand), + List(ListCommand), + Update(UpdateCommand), + Delete(DeleteCommand), +} diff --git a/apps/frilvault-cli/src/cli/update.rs b/apps/frilvault-cli/src/cli/update.rs new file mode 100644 index 0000000..fc5cf31 --- /dev/null +++ b/apps/frilvault-cli/src/cli/update.rs @@ -0,0 +1,13 @@ +use clap::Args; + +#[derive(Debug, Args)] +pub struct UpdateCommand { + #[arg(long)] + pub file: String, + + #[arg(long)] + pub id: String, + + #[arg(long)] + pub content: String, +} diff --git a/apps/frilvault-cli/src/command/add.rs b/apps/frilvault-cli/src/command/add.rs new file mode 100644 index 0000000..6edfe99 --- /dev/null +++ b/apps/frilvault-cli/src/command/add.rs @@ -0,0 +1,24 @@ +use anyhow::Result; + +use frilvault_core::{AddNoteInput, LineAnchor, NoteAnchor}; + +use crate::{cli::add::AddCommand, command::create_note_service}; + +pub fn execute(command: AddCommand) -> Result<()> { + let service = create_note_service()?; + + service.add_note(AddNoteInput { + source_file: command.file.into(), + + anchor: NoteAnchor::Line(LineAnchor { + line: command.line, + column: command.column, + }), + + content: command.content, + })?; + + println!("Note added successfully"); + + Ok(()) +} diff --git a/apps/frilvault-cli/src/command/delete.rs b/apps/frilvault-cli/src/command/delete.rs new file mode 100644 index 0000000..ec71e8f --- /dev/null +++ b/apps/frilvault-cli/src/command/delete.rs @@ -0,0 +1,14 @@ +use anyhow::Result; +use uuid::Uuid; + +use crate::{cli::delete::DeleteCommand, command::create_note_service}; + +pub fn execute(command: DeleteCommand) -> Result<()> { + let service = create_note_service()?; + + service.delete_note(&command.file, Uuid::parse_str(&command.id)?)?; + + println!("Note deleted"); + + Ok(()) +} diff --git a/apps/frilvault-cli/src/command/list.rs b/apps/frilvault-cli/src/command/list.rs new file mode 100644 index 0000000..849ff42 --- /dev/null +++ b/apps/frilvault-cli/src/command/list.rs @@ -0,0 +1,23 @@ +use anyhow::Result; + +use crate::{cli::list::ListCommand, command::create_note_service}; + +pub fn execute(command: ListCommand) -> Result<()> { + let service = create_note_service()?; + + let notes = service.list_notes(&command.file)?; + + println!("Found {} notes", notes.len()); + + for note in notes { + println!("\nID: {}", note.id); + + println!("\nFilename: {:?}", note.source_file); + + println!("Content: {}", note.content); + + println!("Anchor: {:?}", note.anchor); + } + + Ok(()) +} diff --git a/apps/frilvault-cli/src/command/mod.rs b/apps/frilvault-cli/src/command/mod.rs new file mode 100644 index 0000000..8bd27d1 --- /dev/null +++ b/apps/frilvault-cli/src/command/mod.rs @@ -0,0 +1,18 @@ +use anyhow::Result; + +use frilvault_core::{NoteService, PathResolver, YamlNoteRepository}; + +pub mod add; +pub mod delete; +pub mod list; +pub mod update; + +pub fn create_note_service() -> Result { + let workspace_root = std::env::current_dir()?; + + let resolver = PathResolver::new(workspace_root); + + let repository = YamlNoteRepository::new(resolver); + + Ok(NoteService::new(repository)) +} diff --git a/apps/frilvault-cli/src/command/update.rs b/apps/frilvault-cli/src/command/update.rs new file mode 100644 index 0000000..2e028d5 --- /dev/null +++ b/apps/frilvault-cli/src/command/update.rs @@ -0,0 +1,18 @@ +use anyhow::Result; +use uuid::Uuid; + +use crate::{cli::update::UpdateCommand, command::create_note_service}; + +pub fn execute(command: UpdateCommand) -> Result<()> { + let service = create_note_service()?; + + service.update_note( + &command.file, + Uuid::parse_str(&command.id)?, + command.content, + )?; + + println!("Note updated"); + + Ok(()) +} diff --git a/apps/frilvault-cli/src/main.rs b/apps/frilvault-cli/src/main.rs new file mode 100644 index 0000000..2e820eb --- /dev/null +++ b/apps/frilvault-cli/src/main.rs @@ -0,0 +1,30 @@ +mod cli; +mod command; + +use anyhow::Result; +use clap::Parser; +use cli::{Cli, Commands}; + +fn main() -> Result<()> { + let cli = Cli::parse(); + + match cli.command { + Commands::Add(cmd) => { + command::add::execute(cmd)?; + } + + Commands::List(cmd) => { + command::list::execute(cmd)?; + } + + Commands::Update(cmd) => { + command::update::execute(cmd)?; + } + + Commands::Delete(cmd) => { + command::delete::execute(cmd)?; + } + } + + Ok(()) +} diff --git a/apps/frivault-cli/Cargo.toml b/apps/frivault-cli/Cargo.toml deleted file mode 100644 index e1945e8..0000000 --- a/apps/frivault-cli/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "frivault-cli" -version = "0.1.0" -edition = "2024" - -[dependencies] diff --git a/apps/frivault-cli/src/main.rs b/apps/frivault-cli/src/main.rs deleted file mode 100644 index e7a11a9..0000000 --- a/apps/frivault-cli/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/crates/frilvault-core/Cargo.toml b/crates/frilvault-core/Cargo.toml index 95af3cc..e7bb3cf 100644 --- a/crates/frilvault-core/Cargo.toml +++ b/crates/frilvault-core/Cargo.toml @@ -6,6 +6,6 @@ edition = "2024" [dependencies] chrono = { version = "0.4", features = ["serde"] } serde = { version = "1", features = ["derive"] } -serde_yml = "0.0.12" +serde_yml = "0.0.13" thiserror = "2" uuid = { version = "1", features = ["v4", "serde"] } \ No newline at end of file diff --git a/crates/frilvault-core/src/lib.rs b/crates/frilvault-core/src/lib.rs index 932d5a4..03423c1 100644 --- a/crates/frilvault-core/src/lib.rs +++ b/crates/frilvault-core/src/lib.rs @@ -6,7 +6,7 @@ pub mod storage; pub mod workspace; pub use error::FrilVaultError; -pub use note::{AddNoteInput, Note, NoteFile, NoteService}; +pub use note::*; pub use storage::YamlNoteRepository; pub use workspace::{PathResolver, Workspace}; diff --git a/crates/frilvault-core/src/note/service.rs b/crates/frilvault-core/src/note/service.rs index 302a0c1..a2b64e3 100644 --- a/crates/frilvault-core/src/note/service.rs +++ b/crates/frilvault-core/src/note/service.rs @@ -1,5 +1,8 @@ use std::path::Path; +use chrono::Utc; +use uuid::Uuid; + use crate::{ FrilVaultResult, note::{AddNoteInput, Note}, @@ -15,6 +18,17 @@ impl NoteService { Self { repository } } + fn load_notes(&self, source_file: impl AsRef) -> FrilVaultResult> { + Ok(self + .repository + .load_by_source_file(source_file.as_ref())? + .notes) + } + + fn save_notes(&self, source_file: impl AsRef, notes: Vec) -> FrilVaultResult<()> { + self.repository.replace_notes(source_file.as_ref(), notes) + } + pub fn add_note(&self, input: AddNoteInput) -> FrilVaultResult { let note = Note::new(input); @@ -24,8 +38,39 @@ impl NoteService { } pub fn list_notes(&self, source_file: impl AsRef) -> FrilVaultResult> { - let note_file = self.repository.load_by_source_file(source_file.as_ref())?; + self.load_notes(source_file) + } + + pub fn delete_note(&self, source_file: impl AsRef, note_id: Uuid) -> FrilVaultResult<()> { + let source_file = source_file.as_ref(); + + let mut notes = self.load_notes(source_file)?; + + notes.retain(|note| note.id != note_id); + + self.repository.replace_notes(source_file, notes)?; + + Ok(()) + } + + pub fn update_note( + &self, + source_file: impl AsRef, + note_id: Uuid, + content: String, + ) -> FrilVaultResult<()> { + let source_file = source_file.as_ref(); + + let mut notes = self.load_notes(source_file)?; + + if let Some(note) = notes.iter_mut().find(|note| note.id == note_id) { + // TODO: FrilVaultError::NoteNotFound + note.content = content; + note.updated_at = Utc::now(); + } + + self.save_notes(source_file, notes)?; - Ok(note_file.notes) + Ok(()) } } diff --git a/crates/frilvault-core/src/storage/yaml_repository.rs b/crates/frilvault-core/src/storage/yaml_repository.rs index ee80dd3..15a6d8e 100644 --- a/crates/frilvault-core/src/storage/yaml_repository.rs +++ b/crates/frilvault-core/src/storage/yaml_repository.rs @@ -66,4 +66,10 @@ impl YamlNoteRepository { Ok(note_file) } + + pub fn replace_notes(&self, source_file: &Path, notes: Vec) -> FrilVaultResult<()> { + let note_file = NoteFile { notes }; + + self.save_by_source_file(source_file, ¬e_file) + } } diff --git a/crates/frilvault-core/src/tests/note_service_test.rs b/crates/frilvault-core/src/tests/note_service_test.rs index 4e2fa57..c8da77c 100644 --- a/crates/frilvault-core/src/tests/note_service_test.rs +++ b/crates/frilvault-core/src/tests/note_service_test.rs @@ -104,3 +104,73 @@ fn add_note_and_load_note() { fs::remove_dir_all(workspace_root).unwrap(); } + +#[test] +fn delete_note_removes_note() { + let workspace_root = + std::env::temp_dir().join(format!("frilvault-test-{}", uuid::Uuid::new_v4())); + + fs::create_dir_all(&workspace_root).unwrap(); + + let resolver = PathResolver::new(&workspace_root); + + let repository = YamlNoteRepository::new(resolver); + + let service = NoteService::new(repository); + + let note = service + .add_note(AddNoteInput { + source_file: "src/main.rs".into(), + anchor: crate::note::NoteAnchor::Line(crate::note::LineAnchor { + line: 10, + column: 5, + }), + content: "delete me".to_string(), + }) + .unwrap(); + + service.delete_note("src/main.rs", note.id).unwrap(); + + let notes = service.list_notes("src/main.rs").unwrap(); + + assert_eq!(notes.len(), 0); + + fs::remove_dir_all(workspace_root).unwrap(); +} + +#[test] +fn update_note_changes_content() { + let workspace_root = + std::env::temp_dir().join(format!("frilvault-test-{}", uuid::Uuid::new_v4())); + + fs::create_dir_all(&workspace_root).unwrap(); + + let resolver = PathResolver::new(&workspace_root); + + let repository = YamlNoteRepository::new(resolver); + + let service = NoteService::new(repository); + + let note = service + .add_note(AddNoteInput { + source_file: "src/main.rs".into(), + anchor: crate::note::NoteAnchor::Line(crate::note::LineAnchor { + line: 10, + column: 5, + }), + content: "old content".to_string(), + }) + .unwrap(); + + service + .update_note("src/main.rs", note.id, "new content".to_string()) + .unwrap(); + + let notes = service.list_notes("src/main.rs").unwrap(); + + assert_eq!(notes.len(), 1); + + assert_eq!(notes[0].content, "new content"); + + fs::remove_dir_all(workspace_root).unwrap(); +}