1use std::{fmt, str::FromStr};
2
3#[derive(Clone, Copy, Debug, serde::Serialize, serde::Deserialize, PartialEq, Eq, Hash)]
9pub enum Algorithm {
10 HS256,
11 HS384,
12 HS512,
13 ES256,
14 ES384,
15 RS256,
16 RS384,
17 RS512,
18 PS256,
19 PS384,
20 PS512,
21 EdDSA,
22}
23
24impl From<Algorithm> for jsonwebtoken::Algorithm {
25 fn from(val: Algorithm) -> Self {
26 match val {
27 Algorithm::HS256 => jsonwebtoken::Algorithm::HS256,
28 Algorithm::HS384 => jsonwebtoken::Algorithm::HS384,
29 Algorithm::HS512 => jsonwebtoken::Algorithm::HS512,
30 Algorithm::ES256 => jsonwebtoken::Algorithm::ES256,
31 Algorithm::ES384 => jsonwebtoken::Algorithm::ES384,
32 Algorithm::RS256 => jsonwebtoken::Algorithm::RS256,
33 Algorithm::RS384 => jsonwebtoken::Algorithm::RS384,
34 Algorithm::RS512 => jsonwebtoken::Algorithm::RS512,
35 Algorithm::PS256 => jsonwebtoken::Algorithm::PS256,
36 Algorithm::PS384 => jsonwebtoken::Algorithm::PS384,
37 Algorithm::PS512 => jsonwebtoken::Algorithm::PS512,
38 Algorithm::EdDSA => jsonwebtoken::Algorithm::EdDSA,
39 }
40 }
41}
42
43impl FromStr for Algorithm {
44 type Err = anyhow::Error;
45
46 fn from_str(s: &str) -> Result<Self, Self::Err> {
47 match s {
48 "HS256" => Ok(Algorithm::HS256),
49 "HS384" => Ok(Algorithm::HS384),
50 "HS512" => Ok(Algorithm::HS512),
51 "ES256" => Ok(Algorithm::ES256),
52 "ES384" => Ok(Algorithm::ES384),
53 "RS256" => Ok(Algorithm::RS256),
54 "RS384" => Ok(Algorithm::RS384),
55 "RS512" => Ok(Algorithm::RS512),
56 "PS256" => Ok(Algorithm::PS256),
57 "PS384" => Ok(Algorithm::PS384),
58 "PS512" => Ok(Algorithm::PS512),
59 "EdDSA" => Ok(Algorithm::EdDSA),
60 _ => anyhow::bail!("invalid algorithm: {s}"),
61 }
62 }
63}
64
65impl fmt::Display for Algorithm {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 match self {
68 Algorithm::HS256 => write!(f, "HS256"),
69 Algorithm::HS384 => write!(f, "HS384"),
70 Algorithm::HS512 => write!(f, "HS512"),
71 Algorithm::ES256 => write!(f, "ES256"),
72 Algorithm::ES384 => write!(f, "ES384"),
73 Algorithm::RS256 => write!(f, "RS256"),
74 Algorithm::RS384 => write!(f, "RS384"),
75 Algorithm::RS512 => write!(f, "RS512"),
76 Algorithm::PS256 => write!(f, "PS256"),
77 Algorithm::PS384 => write!(f, "PS384"),
78 Algorithm::PS512 => write!(f, "PS512"),
79 Algorithm::EdDSA => write!(f, "EdDSA"),
80 }
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[test]
89 fn test_algorithm_from_str_valid() {
90 assert_eq!(Algorithm::from_str("HS256").unwrap(), Algorithm::HS256);
91 assert_eq!(Algorithm::from_str("HS384").unwrap(), Algorithm::HS384);
92 assert_eq!(Algorithm::from_str("HS512").unwrap(), Algorithm::HS512);
93 assert_eq!(Algorithm::from_str("ES256").unwrap(), Algorithm::ES256);
94 assert_eq!(Algorithm::from_str("ES384").unwrap(), Algorithm::ES384);
95 assert_eq!(Algorithm::from_str("RS256").unwrap(), Algorithm::RS256);
96 assert_eq!(Algorithm::from_str("RS384").unwrap(), Algorithm::RS384);
97 assert_eq!(Algorithm::from_str("RS512").unwrap(), Algorithm::RS512);
98 assert_eq!(Algorithm::from_str("PS256").unwrap(), Algorithm::PS256);
99 assert_eq!(Algorithm::from_str("PS384").unwrap(), Algorithm::PS384);
100 assert_eq!(Algorithm::from_str("PS512").unwrap(), Algorithm::PS512);
101 assert_eq!(Algorithm::from_str("EdDSA").unwrap(), Algorithm::EdDSA);
102 }
103
104 #[test]
105 fn test_algorithm_from_str_invalid() {
106 assert!(Algorithm::from_str("HS128").is_err());
107 assert!(Algorithm::from_str("RS128").is_err());
108 assert!(Algorithm::from_str("ES512").is_err());
109 assert!(Algorithm::from_str("EDDSA").is_err());
110 assert!(Algorithm::from_str("invalid").is_err());
111 assert!(Algorithm::from_str("").is_err());
112 }
113
114 #[test]
115 fn test_algorithm_display() {
116 assert_eq!(Algorithm::HS256.to_string(), "HS256");
117 assert_eq!(Algorithm::HS384.to_string(), "HS384");
118 assert_eq!(Algorithm::HS512.to_string(), "HS512");
119 assert_eq!(Algorithm::ES256.to_string(), "ES256");
120 assert_eq!(Algorithm::ES384.to_string(), "ES384");
121 assert_eq!(Algorithm::RS256.to_string(), "RS256");
122 assert_eq!(Algorithm::RS384.to_string(), "RS384");
123 assert_eq!(Algorithm::RS512.to_string(), "RS512");
124 assert_eq!(Algorithm::PS256.to_string(), "PS256");
125 assert_eq!(Algorithm::PS384.to_string(), "PS384");
126 assert_eq!(Algorithm::PS512.to_string(), "PS512");
127 assert_eq!(Algorithm::EdDSA.to_string(), "EdDSA");
128 }
129
130 #[test]
131 fn test_algorithm_to_jsonwebtoken_algorithm() {
132 assert_eq!(
133 jsonwebtoken::Algorithm::from(Algorithm::HS256),
134 jsonwebtoken::Algorithm::HS256
135 );
136 assert_eq!(
137 jsonwebtoken::Algorithm::from(Algorithm::HS384),
138 jsonwebtoken::Algorithm::HS384
139 );
140 assert_eq!(
141 jsonwebtoken::Algorithm::from(Algorithm::HS512),
142 jsonwebtoken::Algorithm::HS512
143 );
144 assert_eq!(
145 jsonwebtoken::Algorithm::from(Algorithm::ES256),
146 jsonwebtoken::Algorithm::ES256
147 );
148 assert_eq!(
149 jsonwebtoken::Algorithm::from(Algorithm::ES384),
150 jsonwebtoken::Algorithm::ES384
151 );
152 assert_eq!(
153 jsonwebtoken::Algorithm::from(Algorithm::RS256),
154 jsonwebtoken::Algorithm::RS256
155 );
156 assert_eq!(
157 jsonwebtoken::Algorithm::from(Algorithm::RS384),
158 jsonwebtoken::Algorithm::RS384
159 );
160 assert_eq!(
161 jsonwebtoken::Algorithm::from(Algorithm::RS512),
162 jsonwebtoken::Algorithm::RS512
163 );
164 assert_eq!(
165 jsonwebtoken::Algorithm::from(Algorithm::PS256),
166 jsonwebtoken::Algorithm::PS256
167 );
168 assert_eq!(
169 jsonwebtoken::Algorithm::from(Algorithm::PS384),
170 jsonwebtoken::Algorithm::PS384
171 );
172 assert_eq!(
173 jsonwebtoken::Algorithm::from(Algorithm::PS512),
174 jsonwebtoken::Algorithm::PS512
175 );
176 assert_eq!(
177 jsonwebtoken::Algorithm::from(Algorithm::EdDSA),
178 jsonwebtoken::Algorithm::EdDSA
179 );
180 }
181
182 #[test]
183 fn test_algorithm_serde() {
184 let alg = Algorithm::HS256;
185 let json = serde_json::to_string(&alg).unwrap();
186 assert_eq!(json, "\"HS256\"");
187
188 let deserialized: Algorithm = serde_json::from_str(&json).unwrap();
189 assert_eq!(deserialized, alg);
190 }
191
192 #[test]
193 fn test_algorithm_equality() {
194 assert_eq!(Algorithm::HS256, Algorithm::HS256);
195 assert_ne!(Algorithm::HS256, Algorithm::HS384);
196 assert_ne!(Algorithm::HS384, Algorithm::HS512);
197 assert_eq!(Algorithm::ES256, Algorithm::ES256);
198 assert_eq!(Algorithm::ES384, Algorithm::ES384);
199 assert_ne!(Algorithm::HS384, Algorithm::ES256);
200 assert_ne!(Algorithm::ES256, Algorithm::ES384);
201 assert_eq!(Algorithm::RS256, Algorithm::RS256);
202 assert_eq!(Algorithm::RS384, Algorithm::RS384);
203 assert_eq!(Algorithm::RS512, Algorithm::RS512);
204 assert_ne!(Algorithm::RS256, Algorithm::RS512);
205 assert_ne!(Algorithm::RS256, Algorithm::PS256);
206 assert_eq!(Algorithm::PS256, Algorithm::PS256);
207 assert_eq!(Algorithm::PS384, Algorithm::PS384);
208 assert_eq!(Algorithm::PS512, Algorithm::PS512);
209 assert_ne!(Algorithm::PS256, Algorithm::PS512);
210 assert_eq!(Algorithm::EdDSA, Algorithm::EdDSA);
211 assert_ne!(Algorithm::EdDSA, Algorithm::ES256);
212 assert_ne!(Algorithm::EdDSA, Algorithm::RS512);
213 }
214
215 #[test]
216 fn test_algorithm_clone() {
217 let alg = Algorithm::HS256;
218 let cloned = alg;
219 assert_eq!(alg, cloned);
220 }
221}