Notes R Ust: A CLI Note Manager Developed with Rust and Domain-Driven Design (DDD)

This article details Notes R Ust, a Command-Line Interface (CLI) application designed for efficient note management. The tool provides users with the ability to create, find, update, and delete notes, offering a robust and optimized solution for personal organization directly from the terminal.

Key Features

  • Create notes: Allows the addition of new notes, which require a title and content.
  • Find notes: Enables the location of specific notes by their title.
  • Update notes: Facilitates the modification of the content of existing notes.
  • Delete notes: Provides the capability to delete notes that are no longer needed.

Architecture: Domain-Driven Design (DDD)

The Notes R Ust project has been structured following the principles of Domain-Driven Design (DDD), which promotes a clean, modular, and maintainable architecture. This design choice facilitates the separation of concerns and the scalability of the system. The directory organization reflects this approach:

  • src/application: Contains the use cases, which encapsulate business logic and orchestrate interactions between entities and repositories. An example is the CreateNewNote class, which manages the process of creating a new note, interacting with the NoteRepository for its persistence.
  • src/domain: Represents the core of the system, defining the domain's entities and repositories.
    • note.rs: Defines the Note entity, which includes the fields id, title, content, created_at, and updated_at. The validations imposed on this entity state that the title must not be empty and its maximum length is 100 characters, and the content also must not be empty with a limit of 1000 characters. The id is an Option<i64>, allowing it to be None during creation, as it is assigned upon persistence.
    • note_repository.rs: Defines the interface for note persistence. The concrete implementation (impl NoteRepository) manages the connection to the SQLite database and interaction with the notes table. The notes-rust.db database is initialized if it does not exist, creating the notes table with the columns id (INTEGER PRIMARY KEY), title (TEXT NOT NULL), content (TEXT NOT NULL), created_at (TEXT DEFAULT CURRENT_TIMESTAMP), and updated_at (TEXT DEFAULT CURRENT_TIMESTAMP).
  • src/infrastructure: Handles the technical details of the application, including the user interface (CLI) and the data persistence layer.
    • src/infrastructure/ui/cli: Houses the specific implementations of command-line actions, such as create.rs for note creation, delete.rs for deletion, and find.rs for searching.

Execution Flow: Creating a Note

To illustrate the functionality, the note creation process is described:

  • The create action in the CLI layer (src/infrastructure/ui/cli/notes/create.rs) initiates the process after user input .
  • This action invokes the CreateNewNote use case (src/application/use_cases/notes/create.rs), providing the note's title and content .
  • Within CreateNewNote, a Note object is instantiated with the received data, applying the defined validations .
  • Subsequently, the use case utilizes the NoteRepository instance to invoke the save method, which persists the note in the SQLite database .
  • Once saved, the system returns the generated id for the new note

Justification of Technical Decisions and Dependencies

  • Rust: The choice of Rust as the programming language is based on its exceptional performance, memory safety, and robustness in concurrent environments. These characteristics are critical for a CLI application requiring efficiency and reliability.
  • Domain-Driven Design (DDD): The adoption of DDD facilitates a modular design that decouples the domain from the infrastructure and application, allowing for greater adaptability to future technological changes with minimal impact on the core business logic.
  • Validations in the Note Entity: Incorporating data validations (length and non-empty) directly into the Note entity ensures data integrity from its point of creation, preventing the persistence of inconsistent information .
  • chrono: The chrono crate (version "0.4") is used for precise management of timestamps (created_at and updated_at), essential for tracking the note's lifecycle .
  • rusqlite: SQLite, along with the rusqlite crate (version "0.36"), was chosen for its embedded database nature and the simplicity it offers for standalone applications like Notes R Ust, eliminating the need for an external database server. The "bundled" feature ensures that the SQLite library is compiled with the project, simplifying distribution.
  • inquire: This crate (version "0.7.5") is fundamental for building interactive user interfaces in the terminal. The "editor" feature of inquire allows for multi-line text editing, enhancing the user experience when entering or modifying note content.
  • ansi_term: The ansi_term crate (version "0.12") is used to format text in the terminal with colors, improving the readability of messages and information presented to the user.

In summary, Notes R Ust is not merely a functional note manager but also a practical demonstration of applying sound software engineering principles and the efficient use of Rust's capabilities, in conjunction with a set of carefully selected libraries, for the development of high-quality command-line tools. The source code is available at https://github.com/gorkamu/notes-rust.