azure_storage/
stored_access_policy.rsuse azure_core::{date, xml::read_xml};
use time::OffsetDateTime;
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct StoredAccessPolicyList {
pub stored_access: Vec<StoredAccessPolicy>,
}
impl StoredAccessPolicyList {
pub fn new(list: Vec<StoredAccessPolicy>) -> Self {
Self {
stored_access: list,
}
}
pub fn from_xml(bytes: &[u8]) -> azure_core::Result<Self> {
let sis: SignedIdentifiers = read_xml(bytes)?;
Ok(sis.into())
}
pub fn to_xml(&self) -> String {
let mut s = String::new();
s.push_str("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<SignedIdentifiers>\n");
for sa in &self.stored_access {
s.push_str("\t<SignedIdentifier>\n");
s.push_str("\t\t<Id>");
s.push_str(&sa.id);
s.push_str("\n\t\t</Id>\n");
s.push_str("<AccessPolicy>\n");
s.push_str("\t\t\t<Start>");
s.push_str(&date::to_rfc3339(&sa.start));
s.push_str("</Start>\n");
s.push_str("\t\t\t<Expiry>");
s.push_str(&date::to_rfc3339(&sa.expiry));
s.push_str("</Expiry>\n");
s.push_str("\t\t\t<Permission>");
s.push_str(&sa.permission);
s.push_str("</Permission>\n");
s.push_str("\t\t</AccessPolicy>\n\t</SignedIdentifier>\n");
}
s.push_str("</SignedIdentifiers>");
s
}
}
impl From<SignedIdentifiers> for StoredAccessPolicyList {
fn from(si: SignedIdentifiers) -> Self {
let list = si
.signed_identifiers
.into_iter()
.map(|si| StoredAccessPolicy {
id: si.id,
start: si.access_policy.start,
expiry: si.access_policy.expiry,
permission: si.access_policy.permission,
})
.collect();
Self {
stored_access: list,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StoredAccessPolicy {
pub id: String,
pub start: OffsetDateTime,
pub expiry: OffsetDateTime,
pub permission: String,
}
impl StoredAccessPolicy {
pub fn new<A, B>(id: A, start: OffsetDateTime, expiry: OffsetDateTime, permission: B) -> Self
where
A: Into<String>,
B: Into<String>,
{
Self {
id: id.into(),
start,
expiry,
permission: permission.into(),
}
}
}
#[derive(Debug, Deserialize)]
struct SignedIdentifiers {
#[serde(rename = "SignedIdentifier", default)]
signed_identifiers: Vec<SignedIdentifier>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct SignedIdentifier {
id: String,
access_policy: AccessPolicy,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct AccessPolicy {
#[serde(with = "azure_core::date::rfc3339")]
start: OffsetDateTime,
#[serde(with = "azure_core::date::rfc3339")]
expiry: OffsetDateTime,
permission: String,
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn parse_from_xml() {
let resp = "<?xml version=\"1.0\" encoding=\"utf-8\"?>
<SignedIdentifiers>
<SignedIdentifier>
<Id>MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=</Id>
<AccessPolicy>
<Start>2009-09-28T08:49:37Z</Start>
<Expiry>2009-09-29T08:49:37Z</Expiry>
<Permission>rwd</Permission>
</AccessPolicy>
</SignedIdentifier>
<SignedIdentifier>
<Id>000zNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=</Id>
<AccessPolicy>
<Start>2018-09-28T08:49:37Z</Start>
<Expiry>2020-09-29T08:49:37Z</Expiry>
<Permission>rd</Permission>
</AccessPolicy>
</SignedIdentifier>
</SignedIdentifiers>";
let sis: SignedIdentifiers = read_xml(resp.as_bytes()).unwrap();
assert_eq!(sis.signed_identifiers.len(), 2);
let sap: StoredAccessPolicyList = sis.into();
let sxml = sap.to_xml();
fn remove_whitespace(mut s: String) -> String {
s.retain(|c| !c.is_whitespace());
s
}
assert_eq!(remove_whitespace(sxml), remove_whitespace(resp.to_owned()));
}
}