Skip to main content

DataStorage

Struct DataStorage 

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

Cross-platform data storage path manager.

The DataStorage struct provides a centralized way to manage file paths for application data across different operating systems. It encapsulates platform-specific logic and provides a consistent interface for path resolution and directory management.

ยงDesign Philosophy

The storage manager follows these principles:

  • Platform Compliance: Adheres to OS-specific directory conventions
  • User-Centric: Stores data in user-accessible locations
  • Predictable: Provides consistent behavior across platforms
  • Robust: Handles edge cases and permission issues gracefully

ยงInitialization

The base path is determined during construction based on:

  1. Operating system detection
  2. Environment variable resolution
  3. Fallback to safe defaults if needed
  4. Organization and application name incorporation

ยงThread Safety

The struct is designed to be used safely across multiple threads, as path resolution is deterministic and doesnโ€™t modify internal state.

Implementationsยง

Sourceยง

impl DataStorage

Source

pub fn new() -> Self

Creates a new DataStorage instance with platform-appropriate base path.

This constructor performs automatic platform detection and constructs the appropriate base directory path following OS conventions. It uses environment variables where available and falls back to safe defaults.

ยงPlatform Resolution Logic

The constructor determines the base path using this priority order:

  1. Environment Variables: Uses OS-specific environment variables
  2. Fallback Values: Uses current directory if environment vars fail
  3. Path Construction: Appends organization and application names
  4. Validation: Ensures the resulting path is usable
ยงApplication Metadata Integration

The method uses compile-time metadata to construct paths:

  • APP_METADATA_OWNER: Organization name (e.g., โ€œlacoddaโ€)
  • APP_METADATA_NAME: Application name (e.g., โ€œkaslโ€)

This ensures consistent branding and path structure across builds.

ยงReturns

Returns a new DataStorage instance configured for the current platform and user environment.

ยงExample
use kasl::libs::data_storage::DataStorage;

// Create platform-specific storage manager
let storage = DataStorage::new();

// Base path is automatically configured; resolve a file within it
let db_path = storage.get_path("kasl.db")?;
println!("Database path: {:?}", db_path);
ยงEnvironment Variable Usage
  • Windows: Uses LOCALAPPDATA for local application data
  • macOS: Uses HOME to construct ~/Library/Application Support path
  • Linux: Uses HOME to construct ~/.local/share path
ยงError Resilience

If environment variables are not available, the constructor:

  • Falls back to current directory (โ€œ.โ€)
  • Continues with path construction
  • Defers directory creation until first access
  • Allows application to function in restricted environments
Source

pub fn get_path(&self, file_name: &str) -> Result<PathBuf>

Resolves a filename to a complete path within the application data directory.

This method takes a filename and returns the complete path where that file should be stored within the applicationโ€™s data directory. It automatically handles directory creation and ensures the path is ready for file operations.

ยงDirectory Creation

The method ensures that all necessary parent directories exist:

  • Creates the entire directory tree if missing
  • Uses OS-appropriate permissions for new directories
  • Handles concurrent access scenarios safely
  • Provides clear error messages if creation fails
ยงPath Construction

The resulting path combines:

  1. Base Path: Platform-specific application data directory
  2. Organization: Namespace isolation (e.g., โ€œlacoddaโ€)
  3. Application: Application-specific subdirectory (e.g., โ€œkaslโ€)
  4. Filename: The requested file within the application directory
ยงArguments
  • file_name - Name of the file to resolve to a full path
ยงReturns

Returns the complete PathBuf where the file should be stored, or an error if directory creation fails or paths are invalid.

ยงExample
use kasl::libs::data_storage::DataStorage;

let storage = DataStorage::new();

// Get path for database file
let db_path = storage.get_path("kasl.db")?;
// Result: /home/user/.local/share/lacodda/kasl/kasl.db (Linux)
//         C:\Users\User\AppData\Local\lacodda\kasl\kasl.db (Windows)

// Get path for configuration file
let config_path = storage.get_path("config.json")?;

// Get path for session cache
let session_path = storage.get_path(".jira_session_id")?;
ยงFile Naming Conventions

The method accepts any valid filename, but common patterns include:

  • Database files: kasl.db, backup.db
  • Configuration: config.json, settings.toml
  • Cache files: .session_id, .auth_token
  • Process files: kasl-watch.pid
  • Logs: kasl.log, debug.log
ยงError Scenarios

The method can fail in several situations:

  • Permission Denied: Insufficient permissions to create directories
  • Disk Full: No space available for directory creation
  • Path Too Long: Resulting path exceeds OS limits
  • Invalid Characters: Filename contains invalid characters for the OS
  • Read-Only Filesystem: Target location is mounted read-only
ยงConcurrency Safety

The directory creation process is designed to handle concurrent access:

  • Multiple processes can safely call this method simultaneously
  • Directory creation is atomic where supported by the OS
  • Existing directories are not affected by creation attempts
  • Race conditions in directory creation are handled gracefully

Trait Implementationsยง

Sourceยง

impl Clone for DataStorage

Sourceยง

fn clone(&self) -> DataStorage

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) ยท Sourceยง

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Sourceยง

impl Default for DataStorage

Sourceยง

fn default() -> Self

Returns the โ€œdefault valueโ€ for a type. Read more
Sourceยง

impl<'de> Deserialize<'de> for DataStorage

Sourceยง

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Sourceยง

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Sourceยง

impl<T> CloneToUninit for T
where T: Clone,

Sourceยง

unsafe fn clone_to_uninit(&self, dest: *mut u8)

๐Ÿ”ฌThis is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Sourceยง

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Sourceยง

impl<T> From<T> for T

Sourceยง

fn from(t: T) -> T

Returns the argument unchanged.

Sourceยง

impl<T> Instrument for T

Sourceยง

fn instrument(self, span: Span) -> Instrumented<Self> โ“˜

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Sourceยง

fn in_current_span(self) -> Instrumented<Self> โ“˜

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> NoneValue for T
where T: Default,

Sourceยง

type NoneType = T

Sourceยง

fn null_value() -> T

The none-equivalent value.
Sourceยง

impl<T> NoneValue for T
where T: Default,

Sourceยง

type NoneType = T

Sourceยง

fn null_value() -> T

The none-equivalent value.
Sourceยง

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

Sourceยง

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Sourceยง

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Sourceยง

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Sourceยง

impl<T> Same for T

Sourceยง

type Output = T

Should always be Self
Sourceยง

impl<T> ToOwned for T
where T: Clone,

Sourceยง

type Owned = T

The resulting type after obtaining ownership.
Sourceยง

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Sourceยง

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.
Sourceยง

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Sourceยง

fn vzip(self) -> V

Sourceยง

impl<T> WithSubscriber for T

Sourceยง

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> โ“˜
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Sourceยง

fn with_current_subscriber(self) -> WithDispatch<Self> โ“˜

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more