Skip to main content

SessionStore

Struct SessionStore 

Source
pub struct SessionStore { /* private fields */ }
Expand description

Session storage with NDJSON format.

Stores sessions as NDJSON (Newline Delimited JSON) files where each line is a valid JSON object. This format allows:

  • Streaming writes (append commands during recording)
  • Human readability (one JSON object per line)
  • Crash recovery (partial files are readable up to last complete line)

File structure:

{"type": "header", "version": 2, "id": "...", ...}
{"type": "command", "index": 0, "command": "...", ...}
{"type": "command", "index": 1, "command": "...", ...}
{"type": "footer", "ended_at": ..., "command_count": ..., "status": "..."}

Implementations§

Source§

impl SessionStore

Source

pub fn new(paths: Paths) -> Self

Create a new SessionStore with the given paths.

Source

pub fn save(&self, session: &Session) -> Result<()>

Save a complete session to NDJSON file atomically.

Uses a write-to-temp-then-rename pattern for crash safety:

  1. Write to a temporary file ({uuid}.ndjson.tmp)
  2. Flush and sync to disk
  3. Atomically rename to final location (POSIX rename is atomic)

This ensures the session file is never left in a partial state. If a crash occurs during write, only the .tmp file is affected.

§Errors

Returns an error if:

  • Directory creation fails
  • File creation fails
  • JSON serialization fails
  • Atomic rename fails
Source

pub fn load(&self, id: &str) -> Result<Session>

Load a session from NDJSON file.

Reads the NDJSON file line by line and reconstructs the Session struct from the header, commands, and optional footer.

§Errors

Returns an error if:

  • Session file doesn’t exist
  • File read fails
  • JSON parsing fails
  • File is missing the header
Source

pub fn list(&self) -> Result<Vec<String>>

List all session IDs in the data directory.

Returns the file stems (IDs) of all .ndjson files in the sessions directory.

§Errors

Returns an error if reading the directory fails.

Source

pub fn delete(&self, id: &str) -> Result<()>

Delete a session by ID.

Removes the session file from disk.

§Errors

Returns an error if the session doesn’t exist or deletion fails.

Load only the header and footer from a session file.

Much more efficient than load() for listing because it skips command deserialization. Reads the file line by line:

  • Parses the first non-empty line as the header
  • Tracks the last non-empty line and tries parsing it as a footer
§Errors

Returns an error if:

  • Session file doesn’t exist
  • File read fails
  • Header is missing or invalid
Source

pub fn rename(&self, id: &str, new_name: &str) -> Result<()>

Rename a session by updating the name in its NDJSON file.

Creates a backup of the original file before modifying. Loads the full session, updates the name, and saves it back.

§Errors

Returns an error if:

  • Session doesn’t exist
  • Backup creation fails
  • File write fails
Source

pub fn add_tags(&self, id: &str, tags: Vec<String>) -> Result<Vec<String>>

Add tags to a session, skipping duplicates.

Creates a backup of the original file before modifying. Returns the final list of all tags on the session.

§Errors

Returns an error if:

  • Session doesn’t exist
  • Backup creation fails
  • File write fails
Source

pub fn exists(&self, id: &str) -> bool

Check if a session exists.

Source

pub fn session_file_path(&self, id: &str) -> PathBuf

Get the file path for a session by ID.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.