1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use std::fmt::{self, Debug, Formatter};
use serde::{Deserialize, Deserializer};
use time::PrimitiveDateTime;
use super::{Credentials, RotatingCredentials};
#[derive(Clone, Deserialize)]
pub struct Ec2SecurityCredentialsMetadataResponse {
#[serde(rename = "AccessKeyId")]
key: String,
#[serde(rename = "SecretAccessKey")]
secret: String,
#[serde(rename = "Token")]
token: String,
#[serde(rename = "Expiration", deserialize_with = "expiration_deserializer")]
expiration: PrimitiveDateTime,
}
fn expiration_deserializer<'de, D>(deserializer: D) -> Result<PrimitiveDateTime, D::Error>
where
D: Deserializer<'de>,
{
let s: &str = Deserialize::deserialize(deserializer)?;
PrimitiveDateTime::parse(s, "%Y-%m-%dT%H:%M:%SZ").map_err(serde::de::Error::custom)
}
impl Ec2SecurityCredentialsMetadataResponse {
pub fn deserialize(s: &str) -> Result<Self, serde_json::Error> {
serde_json::from_str(s)
}
#[inline]
pub fn key(&self) -> &str {
&self.key
}
#[inline]
pub fn secret(&self) -> &str {
&self.secret
}
#[inline]
pub fn token(&self) -> &str {
&self.token
}
#[inline]
pub fn expiration(&self) -> PrimitiveDateTime {
self.expiration
}
#[inline]
pub fn into_credentials(self) -> Credentials {
Credentials::new_(self.key, self.secret, Some(self.token))
}
#[inline]
pub fn rotate_credentials(self, rotating: &RotatingCredentials) {
rotating.update(self.key, self.secret, Some(self.token));
}
}
impl Debug for Ec2SecurityCredentialsMetadataResponse {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("Ec2SecurityCredentialsMetadataResponse")
.field("key", &self.key)
.finish()
}
}
#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;
use super::*;
#[test]
fn deserialize() {
let json = r#"{
"Code" : "Success",
"LastUpdated" : "2020-12-28T16:47:50Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "some_access_key",
"SecretAccessKey" : "some_secret_key",
"Token" : "some_token",
"Expiration" : "2020-12-28T23:10:09Z"
}"#;
let deserialized = Ec2SecurityCredentialsMetadataResponse::deserialize(json).unwrap();
assert_eq!(deserialized.key(), "some_access_key");
assert_eq!(deserialized.secret(), "some_secret_key");
assert_eq!(deserialized.token(), "some_token");
assert_eq!(
deserialized.expiration().format("%Y-%m-%dT%H:%M:%SZ"),
"2020-12-28T23:10:09Z"
);
let debug_output = format!("{:?}", deserialized);
assert_eq!(
debug_output,
"Ec2SecurityCredentialsMetadataResponse { key: \"some_access_key\" }"
);
}
}