177 lines
4.9 KiB
Rust
177 lines
4.9 KiB
Rust
//! S3 XML response formatting
|
|
|
|
use quick_xml::se::to_string as xml_to_string;
|
|
use serde::Serialize;
|
|
|
|
/// S3 error response
|
|
#[derive(Debug, Serialize)]
|
|
#[serde(rename = "Error")]
|
|
pub struct ErrorResponse {
|
|
#[serde(rename = "Code")]
|
|
pub code: String,
|
|
#[serde(rename = "Message")]
|
|
pub message: String,
|
|
#[serde(rename = "Resource")]
|
|
pub resource: String,
|
|
#[serde(rename = "RequestId")]
|
|
pub request_id: String,
|
|
}
|
|
|
|
impl ErrorResponse {
|
|
pub fn to_xml(&self) -> String {
|
|
format!(
|
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n{}",
|
|
xml_to_string(self).unwrap_or_default()
|
|
)
|
|
}
|
|
}
|
|
|
|
/// ListAllMyBucketsResult for ListBuckets
|
|
#[derive(Debug, Serialize)]
|
|
#[serde(rename = "ListAllMyBucketsResult")]
|
|
pub struct ListAllMyBucketsResult {
|
|
#[serde(rename = "Owner")]
|
|
pub owner: Owner,
|
|
#[serde(rename = "Buckets")]
|
|
pub buckets: Buckets,
|
|
}
|
|
|
|
#[derive(Debug, Serialize)]
|
|
pub struct Owner {
|
|
#[serde(rename = "ID")]
|
|
pub id: String,
|
|
#[serde(rename = "DisplayName")]
|
|
pub display_name: String,
|
|
}
|
|
|
|
#[derive(Debug, Serialize)]
|
|
pub struct Buckets {
|
|
#[serde(rename = "Bucket", default)]
|
|
pub bucket: Vec<BucketEntry>,
|
|
}
|
|
|
|
#[derive(Debug, Serialize)]
|
|
pub struct BucketEntry {
|
|
#[serde(rename = "Name")]
|
|
pub name: String,
|
|
#[serde(rename = "CreationDate")]
|
|
pub creation_date: String,
|
|
}
|
|
|
|
/// ListBucketResult for ListObjects (v1)
|
|
#[derive(Debug, Serialize)]
|
|
#[serde(rename = "ListBucketResult")]
|
|
pub struct ListBucketResult {
|
|
#[serde(rename = "Name")]
|
|
pub name: String,
|
|
#[serde(rename = "Prefix")]
|
|
pub prefix: String,
|
|
#[serde(rename = "Marker")]
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub marker: Option<String>,
|
|
#[serde(rename = "Delimiter")]
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub delimiter: Option<String>,
|
|
#[serde(rename = "MaxKeys")]
|
|
pub max_keys: u32,
|
|
#[serde(rename = "IsTruncated")]
|
|
pub is_truncated: bool,
|
|
#[serde(rename = "NextMarker")]
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub next_marker: Option<String>,
|
|
#[serde(rename = "Contents", default)]
|
|
pub contents: Vec<ObjectEntry>,
|
|
#[serde(rename = "CommonPrefixes", default)]
|
|
#[serde(skip_serializing_if = "Vec::is_empty")]
|
|
pub common_prefixes: Vec<CommonPrefix>,
|
|
}
|
|
|
|
/// ListBucketResult for ListObjectsV2 (v2)
|
|
#[derive(Debug, Serialize)]
|
|
#[serde(rename = "ListBucketResult")]
|
|
pub struct ListBucketResultV2 {
|
|
#[serde(rename = "Name")]
|
|
pub name: String,
|
|
#[serde(rename = "Prefix")]
|
|
pub prefix: String,
|
|
#[serde(rename = "Delimiter")]
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub delimiter: Option<String>,
|
|
#[serde(rename = "MaxKeys")]
|
|
pub max_keys: u32,
|
|
#[serde(rename = "KeyCount")]
|
|
pub key_count: u32,
|
|
#[serde(rename = "IsTruncated")]
|
|
pub is_truncated: bool,
|
|
#[serde(rename = "ContinuationToken")]
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub continuation_token: Option<String>,
|
|
#[serde(rename = "NextContinuationToken")]
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub next_continuation_token: Option<String>,
|
|
#[serde(rename = "StartAfter")]
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub start_after: Option<String>,
|
|
#[serde(rename = "Contents", default)]
|
|
pub contents: Vec<ObjectEntry>,
|
|
#[serde(rename = "CommonPrefixes", default)]
|
|
#[serde(skip_serializing_if = "Vec::is_empty")]
|
|
pub common_prefixes: Vec<CommonPrefix>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize)]
|
|
pub struct ObjectEntry {
|
|
#[serde(rename = "Key")]
|
|
pub key: String,
|
|
#[serde(rename = "LastModified")]
|
|
pub last_modified: String,
|
|
#[serde(rename = "ETag")]
|
|
pub etag: String,
|
|
#[serde(rename = "Size")]
|
|
pub size: u64,
|
|
#[serde(rename = "StorageClass")]
|
|
pub storage_class: String,
|
|
}
|
|
|
|
#[derive(Debug, Serialize)]
|
|
pub struct CommonPrefix {
|
|
#[serde(rename = "Prefix")]
|
|
pub prefix: String,
|
|
}
|
|
|
|
/// InitiateMultipartUploadResult
|
|
#[derive(Debug, Serialize)]
|
|
#[serde(rename = "InitiateMultipartUploadResult")]
|
|
#[allow(dead_code)]
|
|
pub struct InitiateMultipartUploadResult {
|
|
#[serde(rename = "Bucket")]
|
|
pub bucket: String,
|
|
#[serde(rename = "Key")]
|
|
pub key: String,
|
|
#[serde(rename = "UploadId")]
|
|
pub upload_id: String,
|
|
}
|
|
|
|
/// CompleteMultipartUploadResult
|
|
#[derive(Debug, Serialize)]
|
|
#[serde(rename = "CompleteMultipartUploadResult")]
|
|
#[allow(dead_code)]
|
|
pub struct CompleteMultipartUploadResult {
|
|
#[serde(rename = "Location")]
|
|
pub location: String,
|
|
#[serde(rename = "Bucket")]
|
|
pub bucket: String,
|
|
#[serde(rename = "Key")]
|
|
pub key: String,
|
|
#[serde(rename = "ETag")]
|
|
pub etag: String,
|
|
}
|
|
|
|
/// Convert to XML with declaration
|
|
pub fn to_xml<T: Serialize>(value: &T) -> Result<String, quick_xml::DeError> {
|
|
let xml = xml_to_string(value)?;
|
|
Ok(format!(
|
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n{}",
|
|
xml
|
|
))
|
|
}
|