use std::iter::zip;
use indexmap::IndexMap;
use json_unflattening::{flattening::flatten, unflattening::unflatten};
use serde::{Deserialize, Serialize};
use serde_json::{Value, json, Map, value::Index};
use super::payloads::Payloads;
#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)]
pub struct Claims (pub Vec<String>);
#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)]
pub struct CustomValue {
value: Value,
#[serde(skip_serializing)]
flattening: bool
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)]
pub struct JptClaims {
#[serde(skip_serializing_if = "Option::is_none")]
pub iss: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sub: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub exp: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub nbf: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub iat: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub jti: Option<String>,
#[serde(flatten)]
pub custom: IndexMap<String, Value>
}
impl JptClaims {
pub fn new() -> Self {
Self {
iss: None,
sub: None,
exp: None,
nbf: None,
iat: None,
jti: None,
custom: IndexMap::new() }
}
pub fn set_iss(&mut self, value: String) {
self.iss = Some(value);
}
pub fn set_sub(&mut self, value: String) {
self.sub = Some(value);
}
pub fn set_exp(&mut self, value: i64) {
self.exp = Some(value);
}
pub fn set_nbf(&mut self, value: i64) {
self.nbf = Some(value);
}
pub fn set_iat(&mut self, value: i64) {
self.iat = Some(value);
}
pub fn set_jti(&mut self, value: String) {
self.jti = Some(value);
}
pub fn set_claim<T: Serialize>(&mut self, claim: Option<&str>, value: T, flattened: bool) {
let serde_value = serde_json::to_value(value).unwrap();
if !serde_value.is_object() {
self.custom.insert(claim.unwrap_or("").to_string(), serde_value);
} else {
if flattened {
let v = match claim {
Some(c) => json!({c: serde_value}),
None => serde_value,
};
self.custom.extend(flatten(&v).unwrap());
} else {
self.custom.insert(claim.unwrap_or("").to_string(), serde_value);
}
};
}
pub fn get_claim(&self, claim: &str) -> Option<&Value> {
self.custom.get(claim)
}
pub fn get_claims_and_payloads(&self) -> (Claims, Payloads){
let jptclaims_json_value = serde_json::to_value(self).unwrap();
let claims_payloads_pairs = jptclaims_json_value.as_object().unwrap().to_owned();
let (keys, values): (Vec<String>, Vec<Value>) = claims_payloads_pairs.to_owned().into_iter().unzip();
(Claims(keys), Payloads::new_from_values(values))
}
pub fn from_claims_and_payloads(claims: &Claims, payloads: &Payloads) -> Self {
let zip: Map<String, Value> = zip(claims.0.clone(), payloads.get_values()).collect();
let unflat = unflatten(&zip).unwrap();
let jpt_claims: Self = serde_json::from_value(unflat).unwrap();
jpt_claims
}
}