extrautils

Crates.ioextrautils
lib.rsextrautils
version0.1.0
created_at2025-11-11 16:20:50.568529+00
updated_at2025-11-11 16:20:50.568529+00
descriptionA collection of safe, extra utility functions and abstractions for both std and no_std targets.
homepagehttps://github.com/HackingRepo/extrautils-rs
repositoryhttps://github.com/HackingRepo/extrautils-rs
max_upload_size
id1927514
size358,878
RelunSec (HackingRepo)

documentation

https://docs.rs/extrautils

README

extrautils

crates.io docs.rs License

A comprehensive utility library for Rust, offering both high-level abstractions and low-level primitives for systems programming.

Overview

extrautils is a collection of general-purpose utilities designed to fill gaps in the Rust standard library and provide convenient solutions for common programming patterns. It is designed to be modular, allowing you to pick and choose only the functionality you need via feature flags.

The crate is split into two main categories:

  • High-Level Utilities (std feature): Safe, convenient abstractions for application development, including asynchronous tools, caches, thread pools, and more. Requires the standard library.
  • Low-Level Primitives (lowlevel feature): no_std compatible tools for systems programming, including unsafe helpers for memory manipulation and hardware interaction.

Features

extrautils uses feature flags to control what gets compiled. The default feature enables std.

  • std (default): Enables all high-level utilities that depend on the standard library. This includes:
    • asynchronous: retry logic, SharedRuntime for Tokio.
    • cache: LruCache for in-memory caching.
    • thread: A simple ThreadPool.
    • typemap: A heterogeneous, type-safe container.
    • once_cell: A backport of std::lazy::OnceCell.
    • And many more!
  • lowlevel: Enables no_std compatible, low-level utilities.
    • Volatile: Safe wrapper for volatile memory access.
    • Register: A type for safe, structured access to hardware registers.
    • Bitfield: A macro for creating bitfield structs.
  • serde: Enables serialization/deserialization support for various types via Serde.
  • ctrlc: Enables signal handling utilities.

Installation

Add extrautils to your Cargo.toml:

[dependencies]
extrautils = "0.1.0"

To use only the no_std compatible low-level features, disable the default features:

[dependencies]
extrautils = { version = "0.1.0", default-features = false, features = ["lowlevel"] }

Usage Examples

High-Level: Auto-Retrying an Operation

The retry module provides a simple way to retry a fallible operation with a configurable backoff strategy.

use extrautils::std_only_impls::retry::{retry, RetryConfig, Backoff};
use std::time::Duration;

fn might_fail() -> Result<String, std::io::Error> {
    // Simulate a network request that might fail.
    std::fs::read_to_string("/path/to/a/flaky/resource")
}

fn main() {
    let config = RetryConfig {
        max_attempts: 5,
        backoff: Backoff::Exponential {
            initial: Duration::from_millis(100),
            factor: 2.0,
            max_delay: Some(Duration::from_secs(1)),
        },
    };

    match retry(config, might_fail) {
        Ok(content) => println!("Success: {}", content),
        Err(e) => eprintln!("Operation failed after all retries: {}", e),
    }
}

High-Level: Using a Compile-Time Size Assertion

Ensure your data structures have the expected memory layout, which is critical for FFI or low-level programming.

use extrautils::assert_size;

#[repr(C)]
struct FfiSafePacket {
    header: u32,
    payload: [u8; 12],
}

// This will fail to compile if the size of FfiSafePacket is not 16 bytes.
assert_size!(FfiSafePacket, 16);

Low-Level: no_std Hardware Register Access

When using the lowlevel feature, you can safely interact with memory-mapped registers.

// This example requires `default-features = false` and `features = ["lowlevel"]`
#![no_std]
use extrautils::lowutils::{Register, ReadWrite};

// Define a register at a specific memory address.
const GPIO_CONTROL_REGISTER: *mut u32 = 0x4000_1000 as *mut u32;

fn setup_gpio() {
    let mut gpio_ctrl = unsafe { Register::<u32, ReadWrite>::new(GPIO_CONTROL_REGISTER) };

    // Set the 5th bit to enable a pin, without affecting other bits.
    gpio_ctrl.update(|val| *val |= 1 << 5);
}

License

This project is licensed under the MIT license.

Commit count: 0

cargo fmt