ekv-fs 0.2.0

A chunked, #![no_std] Virtual File System built on top of the Embassy ekv key-value store.
Documentation
//! Key formatting for `ekv` records (`m:{path}` and `c:{path}:{index}`).

use core::fmt::Write;

use heapless::String;

use crate::error::Error;

/// Extra bytes beyond `MAX_PATH_LEN` for the longest key (`c:{path}:{index}`).
pub const KEY_SUFFIX_OVERHEAD: usize = 24;

/// Stack buffer capacity for formatted `ekv` keys.
pub const KEY_BUF_CAP: usize = 128;

/// Key buffer capacity derived from `MAX_PATH_LEN`.
///
/// Covers `c:{path}:{index}` with headroom for the largest `usize` index.
pub const fn max_key_len(max_path_len: usize) -> usize {
    max_path_len + KEY_SUFFIX_OVERHEAD
}

/// Returns `true` if `path` fits in `MAX_PATH_LEN` bytes.
pub const fn path_fits(path_len: usize, max_path_len: usize) -> bool {
    path_len <= max_path_len
}

pub(crate) fn check_path(path: &str, max_path_len: usize) -> Result<(), Error> {
    if path_fits(path.len(), max_path_len) {
        Ok(())
    } else {
        Err(Error::PathTooLong)
    }
}

pub(crate) fn format_meta_key<const N: usize>(
    out: &mut String<N>,
    path: &str,
) -> Result<(), Error> {
    out.clear();
    write!(out, "m:{path}").map_err(|_| Error::KeyTooLong)
}

pub(crate) fn format_chunk_key<const N: usize>(
    out: &mut String<N>,
    path: &str,
    index: usize,
) -> Result<(), Error> {
    out.clear();
    write!(out, "c:{path}:{index}").map_err(|_| Error::KeyTooLong)
}