1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
6pub enum ClaimLabel {
7 Iss = 1, Sub = 2, Aud = 3, Exp = 4, Nbf = 5, Iat = 6, Cti = 7, Cnf = 8, Geohash = 282,
16 Catreplay = 308,
17 Catpor = 309,
18 Catv = 310,
19 Catnip = 311,
20 Catu = 312,
21 Catm = 313,
22 Catalpn = 314,
23 Cath = 315,
24 Catgeoiso3166 = 316,
25 Catgeocoord = 317,
26 Cattpk = 319,
27 Catifdata = 320,
28 Catadpop = 321,
29 Catif = 322,
30 Catr = 323,
31}
32
33pub fn claim_to_label(claim: &str) -> Option<ClaimLabel> {
35 match claim {
36 "iss" => Some(ClaimLabel::Iss),
37 "sub" => Some(ClaimLabel::Sub),
38 "aud" => Some(ClaimLabel::Aud),
39 "exp" => Some(ClaimLabel::Exp),
40 "nbf" => Some(ClaimLabel::Nbf),
41 "iat" => Some(ClaimLabel::Iat),
42 "cti" => Some(ClaimLabel::Cti),
43 "cnf" => Some(ClaimLabel::Cnf),
44 "geohash" => Some(ClaimLabel::Geohash),
45 "catreplay" => Some(ClaimLabel::Catreplay),
46 "catpor" => Some(ClaimLabel::Catpor),
47 "catv" => Some(ClaimLabel::Catv),
48 "catnip" => Some(ClaimLabel::Catnip),
49 "catu" => Some(ClaimLabel::Catu),
50 "catm" => Some(ClaimLabel::Catm),
51 "catalpn" => Some(ClaimLabel::Catalpn),
52 "cath" => Some(ClaimLabel::Cath),
53 "catgeoiso3166" => Some(ClaimLabel::Catgeoiso3166),
54 "catgeocoord" => Some(ClaimLabel::Catgeocoord),
55 "cattpk" => Some(ClaimLabel::Cattpk),
56 "catifdata" => Some(ClaimLabel::Catifdata),
57 "catadpop" => Some(ClaimLabel::Catadpop),
58 "catif" => Some(ClaimLabel::Catif),
59 "catr" => Some(ClaimLabel::Catr),
60 _ => None,
61 }
62}
63
64pub fn label_to_claim(label: ClaimLabel) -> &'static str {
66 match label {
67 ClaimLabel::Iss => "iss",
68 ClaimLabel::Sub => "sub",
69 ClaimLabel::Aud => "aud",
70 ClaimLabel::Exp => "exp",
71 ClaimLabel::Nbf => "nbf",
72 ClaimLabel::Iat => "iat",
73 ClaimLabel::Cti => "cti",
74 ClaimLabel::Cnf => "cnf",
75 ClaimLabel::Geohash => "geohash",
76 ClaimLabel::Catreplay => "catreplay",
77 ClaimLabel::Catpor => "catpor",
78 ClaimLabel::Catv => "catv",
79 ClaimLabel::Catnip => "catnip",
80 ClaimLabel::Catu => "catu",
81 ClaimLabel::Catm => "catm",
82 ClaimLabel::Catalpn => "catalpn",
83 ClaimLabel::Cath => "cath",
84 ClaimLabel::Catgeoiso3166 => "catgeoiso3166",
85 ClaimLabel::Catgeocoord => "catgeocoord",
86 ClaimLabel::Cattpk => "cattpk",
87 ClaimLabel::Catifdata => "catifdata",
88 ClaimLabel::Catadpop => "catadpop",
89 ClaimLabel::Catif => "catif",
90 ClaimLabel::Catr => "catr",
91 }
92}
93
94#[derive(Debug, Clone, Serialize, Deserialize)]
96pub enum ClaimValue {
97 String(String),
98 Integer(i64),
99 Bytes(Vec<u8>),
100 Array(Vec<ClaimValue>),
101 Map(HashMap<String, ClaimValue>),
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct Claim {
107 pub label: ClaimLabel,
108 pub value: ClaimValue,
109}
110
111#[derive(Debug, Clone, Default, Serialize, Deserialize)]
113pub struct Claims {
114 claims: HashMap<ClaimLabel, ClaimValue>,
115}
116
117impl Claims {
118 pub fn new() -> Self {
120 Claims {
121 claims: HashMap::new(),
122 }
123 }
124
125 pub fn add(&mut self, label: ClaimLabel, value: ClaimValue) {
127 self.claims.insert(label, value);
128 }
129
130 pub fn get(&self, label: ClaimLabel) -> Option<&ClaimValue> {
132 self.claims.get(&label)
133 }
134
135 pub fn all(&self) -> &HashMap<ClaimLabel, ClaimValue> {
137 &self.claims
138 }
139
140 pub fn from_map(map: HashMap<String, serde_json::Value>) -> Self {
142 let mut claims = Claims::new();
143
144 for (key, value) in map {
145 if let Some(label) = claim_to_label(&key) {
146 let claim_value = json_to_claim_value(value);
147 claims.add(label, claim_value);
148 }
149 }
150
151 if !claims.claims.contains_key(&ClaimLabel::Catv) {
153 claims.add(ClaimLabel::Catv, ClaimValue::Integer(1));
154 }
155
156 claims
157 }
158
159 pub fn to_map(&self) -> HashMap<String, serde_json::Value> {
161 let mut map = HashMap::new();
162
163 for (label, value) in &self.claims {
164 let key = label_to_claim(*label).to_string();
165 let json_value = claim_value_to_json(value);
166 map.insert(key, json_value);
167 }
168
169 map
170 }
171}
172
173fn json_to_claim_value(value: serde_json::Value) -> ClaimValue {
175 match value {
176 serde_json::Value::String(s) => ClaimValue::String(s),
177 serde_json::Value::Number(n) => {
178 if let Some(i) = n.as_i64() {
179 ClaimValue::Integer(i)
180 } else {
181 ClaimValue::String(n.to_string())
183 }
184 }
185 serde_json::Value::Array(arr) => {
186 let values = arr.into_iter().map(json_to_claim_value).collect();
187 ClaimValue::Array(values)
188 }
189 serde_json::Value::Object(obj) => {
190 let mut map = HashMap::new();
191 for (k, v) in obj {
192 map.insert(k, json_to_claim_value(v));
193 }
194 ClaimValue::Map(map)
195 }
196 serde_json::Value::Bool(b) => ClaimValue::String(b.to_string()),
197 serde_json::Value::Null => ClaimValue::String("null".to_string()),
198 }
199}
200
201fn claim_value_to_json(value: &ClaimValue) -> serde_json::Value {
203 match value {
204 ClaimValue::String(s) => serde_json::Value::String(s.clone()),
205 ClaimValue::Integer(i) => serde_json::Value::Number((*i).into()),
206 ClaimValue::Bytes(b) => {
207 let hex = b
208 .iter()
209 .map(|byte| format!("{byte:02x}"))
210 .collect::<String>();
211 serde_json::Value::String(hex)
212 }
213 ClaimValue::Array(arr) => {
214 let values = arr.iter().map(claim_value_to_json).collect();
215 serde_json::Value::Array(values)
216 }
217 ClaimValue::Map(map) => {
218 let mut obj = serde_json::Map::new();
219 for (k, v) in map {
220 obj.insert(k.clone(), claim_value_to_json(v));
221 }
222 serde_json::Value::Object(obj)
223 }
224 }
225}