pkce_std/
code.rs

1//! Coupled PKCE code verifier and challenge pairs.
2//!
3//! The [`Code`] type provides ergonomic and simple methods to generate verifier-challenge pairs.
4//!
5//! [`Code`] is slightly more than simply using [`Verifier`] and [`Challenge`] together, as it
6//! imposes the following invariant: the verifier and challenge are always generated together and
7//! the challenge corresponds to the verifier, meaning `verifier.verify(&challenge)` is always true.
8//!
9//! Therefore it is not possible to access the verifier or challenge separately, and one should use
10//! [`into_pair`] to get both parts, consuming the [`Code`] value.
11//!
12//! # Examples
13//!
14//! ```
15//! use pkce_std::code::Code;
16//!
17//! let code = Code::generate_default();
18//!
19//! let (verifier, challenge) = code.into_pair();
20//!
21//! // this is always true here!
22//! assert!(verifier.verify(&challenge));
23//! ```
24//!
25//! [`into_pair`]: Code::into_pair
26
27use std::borrow::Cow;
28
29#[cfg(feature = "static")]
30use into_static::IntoStatic;
31
32use crate::{
33    challenge::Challenge, count::Count, length::Length, method::Method, verifier::Verifier,
34};
35
36/// Represents coupled [`Verifier`] and [`Challenge`] pairs.
37///
38/// Refer to the [module] documentation for more information.
39///
40/// [module]: self
41#[derive(Debug, Clone)]
42pub struct Code<'c> {
43    verifier: Verifier<'c>,
44    challenge: Challenge,
45}
46
47impl<'c> Code<'c> {
48    const fn new(verifier: Verifier<'c>, challenge: Challenge) -> Self {
49        Self {
50            verifier,
51            challenge,
52        }
53    }
54
55    /// Consumes [`Self`], returning the `(verifier, challenge)` pair.
56    pub fn into_pair(self) -> Pair<'c> {
57        (self.verifier, self.challenge)
58    }
59
60    /// Consumes [`Self`], returning `(verifier, secret, method)` parts.
61    pub fn into_parts(self) -> Parts<'c> {
62        let (secret, method) = self.challenge.into_parts();
63
64        (self.verifier.take(), secret, method)
65    }
66}
67
68impl Code<'_> {
69    /// Generates [`Self`] using the given method and length.
70    pub fn generate_using(method: Method, length: Length) -> Self {
71        let verifier = Verifier::generate(length);
72        let challenge = verifier.challenge_using(method);
73
74        Self::new(verifier, challenge)
75    }
76
77    /// Generates [`Self`] using the default method and the given length.
78    pub fn generate(length: Length) -> Self {
79        Self::generate_using(Method::default(), length)
80    }
81
82    /// Generates [`Self`] using the default method and length.
83    pub fn generate_default() -> Self {
84        Self::generate(Length::default())
85    }
86
87    /// Generates [`Self`] using the given method and bytes count.
88    pub fn generate_encode_using(method: Method, count: Count) -> Self {
89        let verifier = Verifier::generate_encode(count);
90        let challenge = verifier.challenge_using(method);
91
92        Self::new(verifier, challenge)
93    }
94
95    /// Generates [`Self`] using the default method and the given bytes count.
96    pub fn generate_encode(count: Count) -> Self {
97        Self::generate_encode_using(Method::default(), count)
98    }
99
100    /// Generates [`Self`] using the default method and bytes count.
101    pub fn generate_encode_default() -> Self {
102        Self::generate_encode(Count::default())
103    }
104}
105
106/// An alias for [`Code<'static>`].
107#[cfg(feature = "static")]
108pub type StaticCode = Code<'static>;
109
110#[cfg(feature = "static")]
111impl IntoStatic for Code<'_> {
112    type Static = StaticCode;
113
114    fn into_static(self) -> Self::Static {
115        Self::Static::new(self.verifier.into_static(), self.challenge)
116    }
117}
118
119/// Represents `(verifier, challenge)` pairs.
120pub type Pair<'p> = (Verifier<'p>, Challenge);
121
122/// Represents owned [`Pair`] values.
123pub type OwnedPair = Pair<'static>;
124
125impl<'c> From<Code<'c>> for Pair<'c> {
126    fn from(code: Code<'c>) -> Self {
127        code.into_pair()
128    }
129}
130
131/// Represents `(verifier, secret, method)` parts.
132pub type Parts<'p> = (Cow<'p, str>, String, Method);
133
134/// Represents owned [`Parts`] values.
135pub type OwnedParts = Parts<'static>;
136
137impl<'c> From<Code<'c>> for Parts<'c> {
138    fn from(code: Code<'c>) -> Self {
139        code.into_parts()
140    }
141}