use cbor2::Cbor;
#[derive(Clone, Debug, Default, PartialEq, Cbor)]
#[cbor(tag = 61)]
struct Claims {
#[cbor(key = 1)]
#[serde(rename = "iss", skip_serializing_if = "Option::is_none", default)]
issuer: Option<String>,
#[cbor(key = 2)]
#[serde(rename = "sub", skip_serializing_if = "Option::is_none", default)]
subject: Option<String>,
#[cbor(key = 3)]
#[serde(rename = "aud", skip_serializing_if = "Option::is_none", default)]
audience: Option<String>,
#[cbor(key = 4)]
#[serde(rename = "exp", skip_serializing_if = "Option::is_none", default)]
expiration: Option<u64>,
#[cbor(key = 5)]
#[serde(rename = "nbf", skip_serializing_if = "Option::is_none", default)]
not_before: Option<u64>,
#[cbor(key = 6)]
#[serde(rename = "iat", skip_serializing_if = "Option::is_none", default)]
issued_at: Option<u64>,
#[cbor(key = 7)]
#[serde(
rename = "cti",
with = "serde_bytes",
skip_serializing_if = "Option::is_none",
default
)]
cwt_id: Option<Vec<u8>>,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let claims = Claims {
issuer: Some("coap://as.example.com".into()),
subject: Some("erikw".into()),
audience: Some("coap://light.example.com".into()),
expiration: Some(1444064944),
not_before: Some(1443944944),
issued_at: Some(1443944944),
cwt_id: Some(vec![0x0b, 0x71]),
};
let bytes = cbor2::to_canonical_vec(&claims)?;
assert_eq!(&bytes[..2], &[0xd8, 0x3d]); assert_eq!(
hex::encode(&bytes),
"d83da70175636f61703a2f2f61732e6578616d706c652e636f6d02656572696b77\
037818636f61703a2f2f6c696768742e6578616d706c652e636f6d041a5612aeb0\
051a5610d9f0061a5610d9f007420b71"
);
println!("{}", cbor2::diagnostic(&bytes[..])?);
let from_tagged: Claims = cbor2::from_slice(&bytes)?;
let from_untagged: Claims = cbor2::from_slice(&bytes[2..])?;
assert_eq!(from_tagged, claims);
assert_eq!(from_untagged, claims);
assert_eq!(Claims::TAG, Some(61));
assert_eq!(
Claims::KEYS,
&[
("iss", 1),
("sub", 2),
("aud", 3),
("exp", 4),
("nbf", 5),
("iat", 6),
("cti", 7),
]
);
let json = serde_json::to_string(&claims)?;
let from_json: Claims = serde_json::from_str(&json)?;
assert_eq!(from_json, claims);
println!("{json}");
let minimal = Claims {
issuer: Some("me".into()),
expiration: Some(1444064944),
..Default::default()
};
let minimal_bytes = cbor2::to_canonical_vec(&minimal)?;
println!("{}", cbor2::diagnostic(&minimal_bytes[..])?);
assert_eq!(
serde_json::to_string(&minimal)?,
r#"{"iss":"me","exp":1444064944}"#
);
let now = 1444060000; assert!(claims.expiration.is_some_and(|exp| exp > now)); Ok(())
}