tripfuse 0.1.0

A one-time use container for sensitive values
Documentation
  • Coverage
  • 38.46%
    5 out of 13 items documented0 out of 0 items with examples
  • Size
  • Source code size: 22 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 457.75 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 4s Average build duration of successful builds.
  • all releases: 4s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • oOp995/tripfuse
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • oOp995

tripfuse πŸ”₯

Crates.io Documentation License: MIT

One-time use container for sensitive values - like OTPs, API keys, authenticators, and secrets.

⚑ Features

  • βœ… One-time guarantee - Value can be extracted exactly once
  • βœ… Zero dependencies - No external crates, minimal footprint
  • βœ… No unsafe code - 100% safe Rust
  • βœ… Compile-time enforcement - Prevents accidental reference passing with 'static bound
  • βœ… Explicit burn - Manually destroy the fuse without extracting
  • βœ… Security-focused - Values are moved out, not copied or cloned

Exambles folder follow link examples

πŸš€ Quick Start

use tripfuse::OnceFuse;

// Create a fuse with your secret
let mut fuse = OnceFuse::new(String::from("my_secret_api_key"));

// Use it once - value moves out
let secret = fuse.try_use().unwrap();
println!("Secret: {}", secret);

// Second use fails
assert!(fuse.try_use().is_err());

πŸ“¦Installation

Add to your Cargo.toml:

[dependencies]

tripfuse = "0.1.0"

πŸ”’Security Guarantees

βœ… Do this:

// Owned types are perfect
let fuse = OnceFuse::new(String::from("secret"));
let fuse = OnceFuse::new(vec![1, 2, 3]);
let fuse = OnceFuse::new(MySecretStruct { ... });

// String literals work too
let fuse = OnceFuse::new("hardcoded_secret");

❌ Don't do this:

let secret = String::from("secret");
let fuse = OnceFuse::new(&secret);  // ❌ Won't compile with 'static bound
// secret remains accessible - security risk!

πŸ“– API Overview

  • OnceFuse::new(value) Creates a new fuse, taking ownership of the value.

  • try_use(&mut self) -> Result<T, TripError> Extracts the inner value - succeeds only once.

  • burn_it(&mut self) -> bool Explicitly destroys the fuse. Returns true if this call caused the burn.

  • is_armed(&self) -> bool Checks if the fuse is still usable.

🎯 Use Cases

  • OTP (One-Time Passwords) - Ensure each code is used once

  • API Keys - Prevent key reuse after initial authentication

  • Cryptographic Keys - Move sensitive keys out of memory after use

  • Authenticators - One-time tokens for 2FA

  • Consumable Resources - Any value that should be used exactly once

πŸ”§ Error Handling

use tripfuse::{OnceFuse, TripError};

let mut fuse = OnceFuse::new("secret");

match fuse.try_use() {
    Ok(value) => println!("Got: {}", value),
    Err(TripError::FuseBurntAfterUsage) => println!("Already used!"),
    Err(TripError::FuseBurntExplicitly) => println!("Was explicitly burned!"),
}

πŸ§ͺ Example: OTP Verification

use tripfuse::OnceFuse;

struct OtpCode(String);

fn send_otp() -> OnceFuse<OtpCode> {
    let code = OtpCode("123456".to_string());
    OnceFuse::new(code)
}

fn verify_otp(mut fuse: OnceFuse<OtpCode>, user_input: &str) -> bool {
    match fuse.try_use() {
        Ok(actual) => actual.0 == user_input,
        Err(_) => false,  // Already used!
    }
}

let otp = send_otp();
assert!(verify_otp(otp, "123456"));  // First use - OK
// Second use would fail automatically

πŸ§ͺ Example: OTP Simple Send, Recieve

use tripfuse::{OnceFuse, TripError};

struct Sender<T> {
    otp: OnceFuse<T>,
}
impl<T> Sender<T> {
    fn send(otp: T) -> Self
    //T must implement `PartialEq` + `Eq`
    // and must be 'static to disable the usage
    //of most references
    where
        T: 'static + PartialEq + Eq,
    {
        Self {
            otp: OnceFuse::new(otp),
        }
    }
}
struct Reciever<T> {
    _n: T,
}
impl<T> Reciever<T> {
    fn rcv(mut sender: Sender<T>) -> Result<T, TripError>
    where
        // once again, 'static is not harmfull
        // is not meant to restrict your usage
        // it is been here to force you use owned
        // values not references(at most cases)
        T: 'static,
    {
        sender.otp.try_use()
    }
}

fn main() {
    let rec: Result<i32, TripError> = Reciever::rcv(Sender::send(12502));
    match rec {
        Ok(otp) => {
            println!("received OTP: {}", otp)
        }
        Err(triperror) => match triperror {
            TripError::FuseBurntAfterUsage => {
                println!("the otp has been used earlier")
            }
            TripError::FuseBurntExplicitly => {
                println!("the otp has been explicitly burnt")
            }
            _ => {
                // `TripError` is marked #[non-exhaustive]
                // wild card is necessary in `match`
                unreachable!()
            }
        },
    }
}

🧠 Design Notes

  • Clone is intentionally not implemented - prevents - duplicate access

  • Copy is impossible due to internal state tracking

  • Drop is automatic - no manual cleanup needed

  • Uses std::mem::replace for safe state transitions

πŸ“ License

MIT Β© [oOp995]

🀝 Contributing

Contributions welcome! Please ensure:

  • No external dependencies

  • Maintain 100% test coverage

  • Document all public APIs

  • No unsafe code (unless no other solution exists)

Made with πŸ”’ for security-conscious Rust developers