//! Debug-related utilities.
use core::fmt;

use data_encoding::HEXLOWER_PERMISSIVE;

use crate::crypto::x25519;

/// Formatter to format a slice to its length.
pub(crate) fn debug_slice_length<T: AsRef<[u8]>>(
    slice: T,
    formatter: &mut fmt::Formatter<'_>,
) -> fmt::Result {
    write!(formatter, "length={}", slice.as_ref().len())
}

/// Formatter to redact a string, replacing its content with an equal amount of `*`s.
///
/// Note: The byte length is used for replacing, so the resulting string may not accurately represent the
/// length as humans would perceive it (i.e. graphemes).
pub(crate) fn debug_str_redacted(field: &str, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
    formatter.write_str(&"*".repeat(field.len()))
}

/// Formatter to format bytes as hex.
pub(crate) fn debug_bytes_hex(bytes: &[u8], formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
    formatter.write_str(&HEXLOWER_PERMISSIVE.encode(bytes))
}

/// Formatter to format a [`x25519::StaticSecret`] to its public key.
pub(crate) fn debug_static_secret(
    static_secret: &x25519::StaticSecret,
    formatter: &mut fmt::Formatter<'_>,
) -> fmt::Result {
    debug_bytes_hex(x25519::PublicKey::from(static_secret).as_bytes(), formatter)
}

/// Makes something name-able.
pub(crate) trait Name {
    const NAME: &'static str;
}
