use serde::{Deserialize, Serialize};
pub const DEFAULT_CONTENT_TYPE: &str = "application/octet-stream";
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ObjectMeta {
pub key: String,
pub size: usize,
pub content_type: String,
pub etag: String,
#[serde(default)]
pub metadata: serde_json::Value,
}
#[derive(Debug, thiserror::Error)]
pub enum ObjectError {
#[error("bucket '{0}' not found")]
BucketNotFound(String),
#[error("bucket '{0}' already exists")]
BucketExists(String),
#[error("object '{0}' not found")]
ObjectNotFound(String),
#[error("invalid bucket name '{0}'")]
InvalidBucketName(String),
}
pub fn etag_of(data: &[u8]) -> String {
let mut h: u64 = 0xcbf2_9ce4_8422_2325;
for &b in data {
h ^= b as u64;
h = h.wrapping_mul(0x0000_0100_0000_01b3);
}
format!("{h:016x}")
}
pub fn valid_bucket_name(name: &str) -> bool {
!name.is_empty()
&& name.len() <= 63
&& name
.bytes()
.all(|b| b.is_ascii_lowercase() || b.is_ascii_digit() || b == b'.' || b == b'-')
}