use alloc::{collections::BTreeMap, string::String};
use core::fmt;
use core::str::FromStr;
use chrono::{DateTime, Utc};
#[cfg(feature = "schemars")]
use schemars::JsonSchema;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::{GResult, GreenticError, TenantCtx, validate_identifier};
pub type EventMetadata = BTreeMap<String, String>;
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
#[cfg_attr(feature = "serde", serde(try_from = "String", into = "String"))]
pub struct EventId(String);
impl EventId {
pub fn as_str(&self) -> &str {
&self.0
}
pub fn new(value: impl AsRef<str>) -> GResult<Self> {
value.as_ref().parse()
}
pub fn into_inner(self) -> String {
self.0
}
}
impl From<EventId> for String {
fn from(value: EventId) -> Self {
value.0
}
}
impl AsRef<str> for EventId {
fn as_ref(&self) -> &str {
self.as_str()
}
}
impl fmt::Display for EventId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
impl FromStr for EventId {
type Err = GreenticError;
fn from_str(value: &str) -> Result<Self, Self::Err> {
validate_identifier(value, "EventId")?;
Ok(Self(value.to_owned()))
}
}
impl TryFrom<String> for EventId {
type Error = GreenticError;
fn try_from(value: String) -> Result<Self, Self::Error> {
EventId::from_str(&value)
}
}
impl TryFrom<&str> for EventId {
type Error = GreenticError;
fn try_from(value: &str) -> Result<Self, Self::Error> {
EventId::from_str(value)
}
}
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "schemars", derive(JsonSchema))]
pub struct EventEnvelope {
pub id: EventId,
pub topic: String,
pub r#type: String,
pub source: String,
pub tenant: TenantCtx,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub subject: Option<String>,
#[cfg_attr(
feature = "schemars",
schemars(with = "String", description = "RFC3339 timestamp in UTC")
)]
pub time: DateTime<Utc>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub correlation_id: Option<String>,
pub payload: Value,
#[cfg_attr(feature = "serde", serde(default))]
pub metadata: EventMetadata,
}