use crate::data_ref::DataRef;
use crate::serde_helpers::de_present;
use acdp_primitives::primitives::*;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Body {
pub ctx_id: CtxId,
pub lineage_id: LineageId,
pub origin_registry: String,
pub created_at: DateTime<Utc>,
pub content_hash: ContentHash,
pub signature: Signature,
pub version: u32,
pub supersedes: Option<CtxId>,
pub agent_id: AgentDid,
pub contributors: Vec<AgentDid>,
pub title: String,
#[serde(rename = "type")]
pub context_type: ContextType,
pub data_refs: Vec<DataRef>,
pub derived_from: Vec<CtxId>,
pub visibility: Visibility,
#[serde(skip_serializing_if = "Option::is_none")]
pub audience: Option<Vec<AgentDid>>,
#[serde(
default,
deserialize_with = "de_present",
skip_serializing_if = "Option::is_none"
)]
pub acdp_version: Option<String>,
#[serde(
default,
deserialize_with = "de_present",
skip_serializing_if = "Option::is_none"
)]
pub description: Option<String>,
#[serde(
default,
deserialize_with = "de_present",
skip_serializing_if = "Option::is_none"
)]
pub summary: Option<String>,
#[serde(
default,
deserialize_with = "de_present",
skip_serializing_if = "Option::is_none"
)]
pub tags: Option<Vec<String>>,
#[serde(
default,
deserialize_with = "de_present",
skip_serializing_if = "Option::is_none"
)]
pub domain: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub expires_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub data_period: Option<DataPeriod>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<serde_json::Value>,
#[serde(
default,
deserialize_with = "de_present",
skip_serializing_if = "Option::is_none"
)]
pub schema_uri: Option<String>,
#[serde(flatten)]
pub extensions: serde_json::Map<String, serde_json::Value>,
}
impl Body {
pub fn from_publish_request(
req: &crate::publish::PublishRequest,
ctx_id: CtxId,
lineage_id: LineageId,
origin_registry: impl Into<String>,
created_at: DateTime<Utc>,
) -> Self {
Body {
ctx_id,
lineage_id,
origin_registry: origin_registry.into(),
created_at: acdp_primitives::time::trunc_ms(created_at),
content_hash: req.content_hash.clone(),
signature: req.signature.clone(),
version: req.version,
supersedes: req.supersedes.clone(),
agent_id: req.agent_id.clone(),
contributors: req.contributors.clone(),
title: req.title.clone(),
context_type: req.context_type.clone(),
data_refs: req.data_refs.clone(),
derived_from: req.derived_from.clone(),
visibility: req.visibility.clone(),
audience: req.audience.clone(),
acdp_version: req.acdp_version.clone(),
description: req.description.clone(),
summary: req.summary.clone(),
tags: req.tags.clone(),
domain: req.domain.clone(),
expires_at: req.expires_at,
data_period: req.data_period.clone(),
metadata: req.metadata.clone(),
schema_uri: req.schema_uri.clone(),
extensions: Default::default(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct DataPeriod {
pub start: DateTime<Utc>,
pub end: DateTime<Utc>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Signature {
pub algorithm: String,
pub key_id: String,
pub value: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RegistryState {
pub status: Status,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub lifecycle_events: Option<Vec<crate::lifecycle::LifecycleEvent>>,
#[serde(flatten)]
pub extensions: serde_json::Map<String, serde_json::Value>,
}
impl RegistryState {
pub fn is_retracted(&self) -> bool {
self.lifecycle_events
.as_deref()
.is_some_and(crate::lifecycle::retraction_state)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FullContext {
pub body: Body,
pub registry_state: RegistryState,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub registry_receipt: Option<serde_json::Value>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub lineage_head_receipt: Option<serde_json::Value>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub log_inclusion: Option<serde_json::Value>,
#[serde(flatten)]
pub extensions: serde_json::Map<String, serde_json::Value>,
}