use super::*;
fn default_bucket_region() -> String {
DEFAULT_BUCKET_REGION.to_string()
}
fn default_tenant_id() -> String {
DEFAULT_TENANT_ID.to_string()
}
fn default_request_payment_payer() -> String {
"BucketOwner".to_string()
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct BucketState {
#[serde(default)]
pub owner: String,
#[serde(default = "default_tenant_id")]
pub tenant_id: String,
#[serde(default = "default_bucket_region")]
pub region: String,
#[serde(default)]
pub created_epoch_seconds: u64,
pub versioning: BucketVersioningStatus,
pub cors_rules: Vec<CorsRule>,
#[serde(default)]
pub logging: Option<String>,
#[serde(default)]
pub website: Option<BucketWebsiteConfiguration>,
pub policy: Option<BucketPolicyState>,
pub tags: BTreeMap<String, String>,
#[serde(default)]
pub accelerate_enabled: bool,
#[serde(default)]
pub abac_enabled: bool,
#[serde(default = "default_request_payment_payer")]
pub request_payment_payer: String,
#[serde(default)]
pub public_access_block: Option<BucketPublicAccessBlockState>,
#[serde(default)]
pub metadata_configuration: Option<BucketMetadataConfiguration>,
#[serde(default)]
pub metadata_table_configuration: Option<BucketMetadataTableConfiguration>,
#[serde(default)]
pub metrics_configurations: BTreeMap<String, MetricsConfiguration>,
#[serde(default)]
pub analytics_configurations: BTreeMap<String, AnalyticsConfiguration>,
#[serde(default)]
pub inventory_configurations: BTreeMap<String, InventoryConfiguration>,
#[serde(default)]
pub intelligent_tiering_configurations: BTreeMap<String, IntelligentTieringConfiguration>,
pub object_lock: BucketObjectLockState,
pub encryption: Option<ServerSideEncryption>,
pub lifecycle_rules: Vec<LifecycleRule>,
pub notification_rules: Vec<NotificationRule>,
pub replication: BucketReplicationState,
#[serde(default)]
pub quota: BucketQuotaConfiguration,
#[serde(default)]
pub request_count: u64,
#[serde(default)]
pub ownership: BucketOwnershipState,
pub objects: BTreeMap<String, ObjectState>,
}
impl Default for BucketState {
fn default() -> Self {
Self {
owner: String::default(),
tenant_id: default_tenant_id(),
region: default_bucket_region(),
created_epoch_seconds: 0,
versioning: BucketVersioningStatus::default(),
cors_rules: Vec::default(),
logging: None,
website: None,
policy: None,
tags: BTreeMap::default(),
accelerate_enabled: false,
abac_enabled: false,
request_payment_payer: default_request_payment_payer(),
public_access_block: None,
metadata_configuration: None,
metadata_table_configuration: None,
metrics_configurations: BTreeMap::default(),
analytics_configurations: BTreeMap::default(),
inventory_configurations: BTreeMap::default(),
intelligent_tiering_configurations: BTreeMap::default(),
object_lock: BucketObjectLockState::default(),
encryption: None,
lifecycle_rules: Vec::default(),
notification_rules: Vec::default(),
replication: BucketReplicationState::default(),
quota: BucketQuotaConfiguration::default(),
request_count: 0,
ownership: BucketOwnershipState::default(),
objects: BTreeMap::default(),
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct BucketPolicyState {
pub json: String,
pub policy: Policy,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct BucketPublicAccessBlockState {
pub block_public_acls: bool,
pub ignore_public_acls: bool,
pub block_public_policy: bool,
pub restrict_public_buckets: bool,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct BucketObjectLockState {
pub enabled: bool,
pub default_retention: Option<ObjectLockDefaultRetention>,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct BucketReplicationState {
pub role: Option<String>,
pub rules: Vec<ReplicationRule>,
#[serde(default)]
pub configured_epoch_seconds: u64,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct BucketOwnershipState {
pub object_ownership: String,
}
impl Default for BucketOwnershipState {
fn default() -> Self {
Self {
object_ownership: "BucketOwnerEnforced".to_string(),
}
}
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct ObjectState {
pub versions: Vec<StoredVersion>,
}
impl ObjectState {
pub(crate) fn next_local_ordinal(&self) -> u64 {
self.versions
.iter()
.map(|version| version.local_ordinal)
.max()
.unwrap_or_default()
+ 1
}
pub(crate) fn normalize_missing_local_ordinals(&mut self) {
let mut used_ordinals = self
.versions
.iter()
.filter_map(|version| (version.local_ordinal > 0).then_some(version.local_ordinal))
.collect::<Vec<_>>();
for index in 0..self.versions.len() {
let version = &mut self.versions[index];
if version.local_ordinal == 0 {
let mut candidate = index as u64 + 1;
while used_ordinals.contains(&candidate) {
candidate += 1;
}
version.local_ordinal = candidate;
used_ordinals.push(candidate);
}
}
}
pub(crate) fn current_version(&self) -> Option<&StoredVersion> {
self.versions
.last()
.and_then(|version| (!version.delete_marker).then_some(version))
}
pub(crate) fn current_version_mut(&mut self) -> Option<&mut StoredVersion> {
self.versions
.last_mut()
.and_then(|version| (!version.delete_marker).then_some(version))
}
pub(crate) fn has_current_version(&self) -> bool {
self.current_version().is_some()
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct StoredVersion {
pub version_id: String,
#[serde(default)]
pub local_ordinal: u64,
pub ciphertext: Ciphertext,
pub etag: String,
pub last_modified_epoch_seconds: u64,
pub metadata: ObjectMetadata,
#[serde(default)]
pub envelope: Option<EnvelopeMetadata>,
#[serde(default)]
pub integrity: IntegrityRecord,
pub tags: BTreeMap<String, String>,
pub lock: ObjectLock,
pub delete_marker: bool,
#[serde(default)]
pub owner: String,
#[serde(default)]
pub replication_status: Option<String>,
}
impl StoredVersion {
pub(crate) fn content_length(&self) -> usize {
self.ciphertext.bytes.len()
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct MultipartUploadState {
pub bucket: String,
pub key: String,
pub metadata: ObjectMetadata,
pub lock: ObjectLock,
pub initiated_epoch_seconds: u64,
pub parts: BTreeMap<u16, MultipartPartState>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct MultipartPartState {
pub etag: String,
pub body: Vec<u8>,
#[serde(default)]
pub checksum_sha256: String,
}