littlefs-rust 0.1.0

Safe Rust API for the LittleFS embedded filesystem
Documentation
# littlefs-rust

Safe Rust API for the [LittleFS](https://github.com/littlefs-project/littlefs) embedded filesystem.

Built on [littlefs-rust-core](https://crates.io/crates/littlefs-rust-core), a function-by-function
Rust port of the C littlefs. **No C toolchain required** — pure Rust, builds on any target.

On-disk format is compatible with upstream LittleFS for interoperability.

## Quick start

```rust
use littlefs_rust::{Config, Filesystem, RamStorage};

let mut storage = RamStorage::new(512, 128);
let config = Config::new(512, 128);

Filesystem::format(&mut storage, &config).unwrap();
let fs = Filesystem::mount(storage, config).unwrap();

fs.write_file("/hello.txt", b"Hello, littlefs!").unwrap();
let data = fs.read_to_vec("/hello.txt").unwrap();
assert_eq!(data, b"Hello, littlefs!");

fs.unmount().unwrap();
```

## Examples

### [ram_hello.rs]examples/ram_hello.rs — write and read a file

Formats a RAM-backed filesystem, writes a string to `/hello.txt`, reads it back, and prints storage
statistics on unmount.

```bash
cargo run -p littlefs-rust --example ram_hello
```

### [ram_tree.rs]examples/ram_tree.rs — directories, rename, remove, and stat

Creates a nested directory tree, lists entries with type and size, renames a file, removes a
subdirectory, and queries filesystem usage.

```bash
cargo run -p littlefs-rust --example ram_tree
```

## Usage

Implement the `Storage` trait for your block device:

```rust
use littlefs_rust::{Storage, Error};

struct MyFlash { /* ... */ }

impl Storage for MyFlash {
    fn read(&mut self, block: u32, offset: u32, buf: &mut [u8]) -> Result<(), Error> {
        // read from flash
        Ok(())
    }

    fn write(&mut self, block: u32, offset: u32, data: &[u8]) -> Result<(), Error> {
        // write to flash
        Ok(())
    }

    fn erase(&mut self, block: u32) -> Result<(), Error> {
        // erase block
        Ok(())
    }

    // sync() has a default no-op implementation
}
```

Then format, mount, and use the filesystem:

```rust
use littlefs_rust::{Config, Filesystem, OpenFlags};

let config = Config::new(4096, 256); // 4KB blocks, 256 blocks = 1MB

Filesystem::format(&mut flash, &config)?;
let fs = Filesystem::mount(flash, config)?;

// Convenience methods
fs.write_file("/data.bin", &payload)?;
let data = fs.read_to_vec("/data.bin")?;

// Directory operations
fs.mkdir("/logs")?;
for entry in fs.list_dir("/")? {
    println!("{} ({:?})", entry.name, entry.file_type);
}

// Fine-grained file access
let file = fs.open("/log.txt", OpenFlags::WRITE | OpenFlags::CREATE | OpenFlags::APPEND)?;
file.write(b"new log line\n")?;
file.close()?;

fs.unmount()?;
```

## Architecture

This crate is a safe wrapper around `littlefs-rust-core`, which is a faithful function-by-function
translation of the C littlefs. The wrapper handles all the unsafe ceremony: raw pointers,
`MaybeUninit`, integer error codes, null-terminated paths, and `unsafe extern "C"` callbacks.

### Interior mutability and multiple open files

`Filesystem` wraps its internal state in a `RefCell`. Each operation borrows the `RefCell` only for
the duration of one core call, then releases it immediately. This means multiple `File` and `ReadDir`
handles can coexist, and you can interleave file operations with directory iteration:

```rust
let mut dir = fs.read_dir("/")?;
while let Some(entry) = dir.next() {
    let entry = entry?;
    // This works — the RefCell borrow was released after dir.next()
    let data = fs.read_to_vec(&format!("/{}", entry.name))?;
}
```

### RAII close

`File` and `ReadDir` implement `Drop`, which closes the underlying handle automatically.
Use explicit `close()` when you need to handle errors from the close operation.

### Heap allocation

The crate requires `alloc`. Internal buffers (caches, lookahead) and file/directory allocations are
heap-allocated via `Box` and `Vec`. This provides stable addresses for the core's internal pointer
structures without requiring `Pin` or self-referential struct tricks.

## Feature flags

| Feature | Default | Description |
|---------|---------|-------------|
| `alloc` | yes | Required. Enables `Vec`, `Box`, and convenience methods. |
| `std`   | no  | Enables `std::error::Error` impl on `Error`. |
| `log`   | no  | Passes through to `littlefs-rust-core` for trace logging. |

## Prior art

- [littlefs2]https://crates.io/crates/littlefs2 — idiomatic Rust API wrapping the C library via FFI (requires C toolchain)
- [littlefs2-sys]https://crates.io/crates/littlefs2-sys — low-level C bindings

## License

BSD-3-Clause (same as upstream littlefs)