Skip to content

Instantly share code, notes, and snippets.

@GriffinHeart
Created November 27, 2023 11:49
Show Gist options
  • Save GriffinHeart/15911f9f4e1e5d90f70d908f3f248027 to your computer and use it in GitHub Desktop.
Save GriffinHeart/15911f9f4e1e5d90f70d908f3f248027 to your computer and use it in GitHub Desktop.
Prevent string from being leaked by accident into output
use std::fmt;
use core::fmt::Debug;
use clap::Parser;
use serde_with::{DeserializeFromStr, SerializeDisplay};
#[derive(Clone, SerializeDisplay, DeserializeFromStr)]
pub struct NoDisplay(String);
impl std::fmt::Display for NoDisplay {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "NoDisplay(*****)")
}
}
impl Debug for NoDisplay {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "NoDisplay(*****)")
}
}
impl std::str::FromStr for NoDisplay {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(NoDisplay(s.to_string()))
}
}
#[derive(Parser, Debug)]
pub struct Args {
#[arg(long, value_parser = clap::value_parser!(NoDisplay))]
pub my_sort_of_secret: NoDisplay,
}
fn main() {
let args = Args::parse();
// doesn't leak
println!("{:?}", args);
println!("{}", args.my_sort_of_secret);
dbg!(&args);
// leaks
println!("{}", args.my_sort_of_secret.0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment