otp_std/auth/
url.rs

1//! URL functionality.
2//!
3//! This module re-exports [`url::Url`] and provides the [`struct@Error`] type
4//! that wraps [`url::ParseError`] to provide diagnostics.
5
6use miette::Diagnostic;
7use thiserror::Error;
8
9pub use url::Url;
10pub use urlencoding::{decode, encode};
11
12use crate::{
13    auth::{label::Label, scheme::SCHEME},
14    otp::Type,
15};
16
17/// Wraps [`url::ParseError`] to provide diagnostics.
18#[derive(Debug, Error, Diagnostic)]
19#[error("failed to parse OTP URL")]
20#[diagnostic(code(otp_std::auth::url), help("make sure the OTP URL is valid"))]
21pub struct Error(#[from] pub url::ParseError);
22
23/// Parses the given string into [`Url`].
24///
25/// # Errors
26///
27/// Returns [`struct@Error`] when the string can not be parsed into URL.
28pub fn parse<S: AsRef<str>>(string: S) -> Result<Url, Error> {
29    Url::parse(string.as_ref()).map_err(Error)
30}
31
32/// The message indicating that the OTP base URL is always valid.
33pub const BASE_ALWAYS_VALID: &str = "OTP base URL is always valid";
34
35/// Returns the base OTP URL for the given type and label.
36///
37/// # Panics
38///
39/// This function can not panic because the base URL is always valid.
40pub fn base(type_of: Type, label: &Label<'_>) -> Url {
41    let string = format!("{SCHEME}://{type_of}/{label}");
42
43    parse(string).expect(BASE_ALWAYS_VALID)
44}