use std::borrow::Cow;
#[cfg(feature = "static")]
use into_static::IntoStatic;
use crate::{
challenge::Challenge, count::Count, length::Length, method::Method, verifier::Verifier,
};
#[derive(Debug, Clone)]
pub struct Code<'c> {
verifier: Verifier<'c>,
challenge: Challenge,
}
impl<'c> Code<'c> {
const fn new(verifier: Verifier<'c>, challenge: Challenge) -> Self {
Self {
verifier,
challenge,
}
}
pub fn into_pair(self) -> Pair<'c> {
(self.verifier, self.challenge)
}
pub fn into_parts(self) -> Parts<'c> {
let (secret, method) = self.challenge.into_parts();
(self.verifier.take(), secret, method)
}
}
impl Code<'_> {
pub fn generate_using(method: Method, length: Length) -> Self {
let verifier = Verifier::generate(length);
let challenge = verifier.challenge_using(method);
Self::new(verifier, challenge)
}
pub fn generate(length: Length) -> Self {
Self::generate_using(Method::default(), length)
}
pub fn generate_default() -> Self {
Self::generate(Length::default())
}
pub fn generate_encode_using(method: Method, count: Count) -> Self {
let verifier = Verifier::generate_encode(count);
let challenge = verifier.challenge_using(method);
Self::new(verifier, challenge)
}
pub fn generate_encode(count: Count) -> Self {
Self::generate_encode_using(Method::default(), count)
}
pub fn generate_encode_default() -> Self {
Self::generate_encode(Count::default())
}
}
#[cfg(feature = "static")]
pub type StaticCode = Code<'static>;
#[cfg(feature = "static")]
impl IntoStatic for Code<'_> {
type Static = StaticCode;
fn into_static(self) -> Self::Static {
Self::Static::new(self.verifier.into_static(), self.challenge)
}
}
pub type Pair<'p> = (Verifier<'p>, Challenge);
pub type OwnedPair = Pair<'static>;
impl<'c> From<Code<'c>> for Pair<'c> {
fn from(code: Code<'c>) -> Self {
code.into_pair()
}
}
pub type Parts<'p> = (Cow<'p, str>, String, Method);
pub type OwnedParts = Parts<'static>;
impl<'c> From<Code<'c>> for Parts<'c> {
fn from(code: Code<'c>) -> Self {
code.into_parts()
}
}