use serde::{Deserialize, Serialize};
use crate::types::EventPayload;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[non_exhaustive]
pub enum StorageOperation {
Upload,
Delete,
Any,
}
impl StorageOperation {
#[must_use]
pub const fn as_str(&self) -> &str {
match self {
StorageOperation::Upload => "upload",
StorageOperation::Delete => "delete",
StorageOperation::Any => "any",
}
}
}
#[derive(Debug, Clone)]
pub struct StorageEventPayload {
pub bucket: String,
pub key: String,
pub size_bytes: i64,
pub content_type: String,
pub owner_id: Option<String>,
pub operation: StorageOperation,
}
#[derive(Debug, Clone)]
pub struct StorageTrigger {
pub function_name: String,
pub bucket: String,
pub operation: StorageOperation,
}
impl StorageTrigger {
#[must_use]
pub fn matches(&self, event: &StorageEventPayload) -> bool {
if self.bucket != event.bucket {
return false;
}
let op_matches = match self.operation {
StorageOperation::Any => true,
_ => self.operation == event.operation,
};
if !op_matches {
return false;
}
if event.key.starts_with("_transforms/") {
return false;
}
true
}
#[must_use]
pub fn should_fire(&self, event: &StorageEventPayload) -> bool {
self.matches(event)
}
#[must_use]
pub fn build_payload(&self, event: &StorageEventPayload) -> EventPayload {
let trigger_type = format!("after:storage:{}:{}", event.bucket, event.operation.as_str());
let mut data = serde_json::json!({
"bucket": event.bucket,
"key": event.key,
"size_bytes": event.size_bytes,
"content_type": event.content_type,
"operation": event.operation.as_str(),
});
if let Some(owner_id) = &event.owner_id {
data["owner_id"] = serde_json::Value::String(owner_id.clone());
}
EventPayload {
trigger_type,
entity: event.bucket.clone(),
event_kind: event.operation.as_str().to_string(),
data,
timestamp: chrono::Utc::now(),
}
}
}