otp_std/auth/
scheme.rs

1//! Authentication scheme.
2
3use const_macros::const_early;
4
5use miette::Diagnostic;
6use thiserror::Error;
7
8use crate::{auth::url::Url, macros::errors};
9
10/// The scheme used in OTP URLs.
11pub const SCHEME: &str = "otpauth";
12
13/// Represents errors that occur when unexpected schemes are encountered.
14///
15/// The only scheme valid for OTP URLs is [`SCHEME`].
16#[derive(Debug, Error, Diagnostic)]
17#[error("unexpected scheme `{scheme}`; expected `{SCHEME}`")]
18#[diagnostic(code(otp_std::auth::scheme), help("make sure the scheme is correct"))]
19pub struct Error {
20    /// The unexpected scheme.
21    pub scheme: String,
22}
23
24impl Error {
25    /// Constructs [`Self`].
26    pub const fn new(scheme: String) -> Self {
27        Self { scheme }
28    }
29}
30
31errors! {
32    Type = Error,
33    Hack = $,
34    error => new(scheme => to_owned),
35}
36
37/// Checks whether the given scheme matches [`SCHEME`].
38///
39/// # Errors
40///
41/// Returns [`struct@Error`] when the scheme does not match [`SCHEME`].
42pub fn check<S: AsRef<str>>(scheme: S) -> Result<(), Error> {
43    fn check_inner(scheme: &str) -> Result<(), Error> {
44        const_early!(scheme != SCHEME => error!(scheme));
45
46        Ok(())
47    }
48
49    check_inner(scheme.as_ref())
50}
51
52/// Checks whether the given URL has the scheme matching [`SCHEME`].
53///
54/// # Errors
55///
56/// Returns [`struct@Error`] when the URL scheme does not match [`SCHEME`].
57pub fn check_url(url: &Url) -> Result<(), Error> {
58    check(url.scheme())
59}