1use std::fmt;
14
15#[cfg(feature = "serde")]
16use serde::{Deserialize, Serialize};
17
18use crate::{encoding::encode, hash::sha256, method::Method, verifier::Verifier};
19
20#[derive(Debug, Clone, PartialEq, Eq, Hash)]
22#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
23pub struct Challenge {
24 secret: String,
25 method: Method,
26}
27
28pub type Parts = (String, Method);
30
31impl fmt::Display for Challenge {
32 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
33 self.secret().fmt(formatter)
34 }
35}
36
37impl Challenge {
38 pub const fn secret(&self) -> &str {
40 self.secret.as_str()
41 }
42
43 pub const fn method(&self) -> Method {
45 self.method
46 }
47
48 pub fn into_parts(self) -> Parts {
50 (self.secret, self.method)
51 }
52}
53
54impl From<Challenge> for Parts {
55 fn from(challenge: Challenge) -> Self {
56 challenge.into_parts()
57 }
58}
59
60impl Challenge {
61 const fn new(secret: String, method: Method) -> Self {
62 Self { secret, method }
63 }
64}
65
66impl Challenge {
67 pub fn create_using(method: Method, verifier: &Verifier<'_>) -> Self {
69 let string = verifier.get();
70
71 let secret = match method {
72 Method::Plain => string.to_owned(),
73 Method::Sha256 => encode(sha256(string)),
74 };
75
76 Self::new(secret, method)
77 }
78
79 pub fn create(verifier: &Verifier<'_>) -> Self {
81 Self::create_using(Method::default(), verifier)
82 }
83}