use const_macros::const_early;
#[cfg(feature = "diagnostics")]
use miette::Diagnostic;
use thiserror::Error;
#[derive(Debug, Error)]
#[error("invalid byte `{byte}` encountered")]
#[cfg_attr(
feature = "diagnostics",
derive(Diagnostic),
diagnostic(code(pkce_std::check::bytes), help("ensure the byte is valid"))
)]
pub struct Error {
pub byte: u8,
}
impl Error {
pub const fn new(byte: u8) -> Self {
Self { byte }
}
}
macro_rules! special_pattern {
() => {
b'-' | b'.' | b'_' | b'~'
};
}
pub const fn is_special(byte: u8) -> bool {
matches!(byte, special_pattern!())
}
pub const fn is_valid(byte: u8) -> bool {
byte.is_ascii_alphanumeric() || is_special(byte)
}
pub const fn check(byte: u8) -> Result<(), Error> {
const_early!(!is_valid(byte) => Error::new(byte));
Ok(())
}