use forte_macros::forte_doc;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
pub use doc_db::DbRequest;
#[derive(Serialize, Deserialize, Clone)]
pub struct WorkerProjectManifest {
pub code_version: u64,
#[serde(
alias = "custom_domain",
default,
deserialize_with = "deserialize_domain"
)]
pub domain: String,
#[serde(default = "default_static_cache_state")]
pub static_cache_state: String,
#[serde(default)]
pub pending_code_version: Option<u64>,
#[serde(default)]
pub storage: Option<WorkerProjectStorage>,
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct WorkerR2Credential {
pub access_key_id: String,
pub secret_ciphertext: String,
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct WorkerProjectStorage {
pub account_id: String,
pub region: String,
pub credential: WorkerR2Credential,
pub private_object_storage_bucket: String,
pub public_object_storage_bucket: String,
pub public_object_storage_base_url: String,
pub config_version: u64,
}
pub const STATIC_CACHE_STATE_ACTIVE: &str = "active";
pub const STATIC_CACHE_STATE_PRE_PURGE: &str = "pre_purge";
pub const STATIC_CACHE_STATE_ACTIVATING: &str = "activating";
fn default_static_cache_state() -> String {
STATIC_CACHE_STATE_ACTIVE.to_string()
}
fn deserialize_domain<'de, D>(deserializer: D) -> Result<String, D::Error>
where
D: serde::Deserializer<'de>,
{
struct DomainVisitor;
impl<'de> serde::de::Visitor<'de> for DomainVisitor {
type Value = String;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a string or null")
}
fn visit_str<E: serde::de::Error>(self, value: &str) -> Result<String, E> {
Ok(value.to_string())
}
fn visit_none<E: serde::de::Error>(self) -> Result<String, E> {
Ok(String::new())
}
fn visit_some<D: serde::Deserializer<'de>>(
self,
deserializer: D,
) -> Result<String, D::Error> {
Deserialize::deserialize(deserializer)
}
}
deserializer.deserialize_option(DomainVisitor)
}
#[cfg(test)]
mod tests {
use super::WorkerProjectManifest;
#[test]
fn domain_reads_the_legacy_custom_domain_key() {
let entry: WorkerProjectManifest =
serde_json::from_str(r#"{"code_version":0,"custom_domain":"app.example.com"}"#)
.unwrap();
assert_eq!(entry.domain, "app.example.com");
}
#[test]
fn null_legacy_domain_reads_as_empty() {
let entry: WorkerProjectManifest =
serde_json::from_str(r#"{"code_version":0,"custom_domain":null}"#).unwrap();
assert_eq!(entry.domain, "");
}
#[test]
fn domain_serializes_under_its_own_name() {
let entry: WorkerProjectManifest =
serde_json::from_str(r#"{"code_version":0,"domain":"app.example.com"}"#).unwrap();
let json = serde_json::to_string(&entry).unwrap();
assert!(json.contains(r#""domain":"app.example.com""#));
assert!(!json.contains("custom_domain"));
}
}
#[forte_doc]
pub struct WorkerManifestDoc {
pub manifest_version: u64,
pub project_manifests: HashMap<String, WorkerProjectManifest>,
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct WorkerHostnameCert {
pub project_id: String,
pub cert_pem: String,
pub key_ciphertext: String,
pub not_after_epoch_seconds: i64,
}
#[forte_doc]
pub struct WorkerCertManifestDoc {
pub cert_version: u64,
pub certs: HashMap<String, WorkerHostnameCert>,
}
#[forte_doc]
pub struct WorkerHostStatusDoc {
#[sk]
pub host_id: String,
pub addr: String,
pub active_image_ref: Option<String>,
pub reported_at: i64,
}
#[forte_doc]
pub struct WebSocketConnectionDoc {
#[sk]
pub connection_id: String,
pub project_id: String,
pub worker_id: String,
pub endpoint: String,
}
#[forte_doc]
pub struct WebSocketDirectoryGcCursorDoc {
pub after_connection_id: Option<String>,
}