1use 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#[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 pub fn into_pair(self) -> Pair<'c> {
57 (self.verifier, self.challenge)
58 }
59
60 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 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 pub fn generate(length: Length) -> Self {
79 Self::generate_using(Method::default(), length)
80 }
81
82 pub fn generate_default() -> Self {
84 Self::generate(Length::default())
85 }
86
87 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 pub fn generate_encode(count: Count) -> Self {
97 Self::generate_encode_using(Method::default(), count)
98 }
99
100 pub fn generate_encode_default() -> Self {
102 Self::generate_encode(Count::default())
103 }
104}
105
106#[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
119pub type Pair<'p> = (Verifier<'p>, Challenge);
121
122pub 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
131pub type Parts<'p> = (Cow<'p, str>, String, Method);
133
134pub 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}