use serde::Serialize;
#[derive(Debug, Clone)]
pub enum RawEventAction {
Created {
status: String,
},
StatusChanged {
from: String,
to: String,
},
Other(String),
}
pub mod raw_event_action {
use super::RawEventAction;
use serde::de::{self, MapAccess, Visitor};
use serde::Deserializer;
use std::fmt;
pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<RawEventAction, D::Error> {
d.deserialize_map(RawEventActionVisitor)
}
struct RawEventActionVisitor;
impl<'de> Visitor<'de> for RawEventActionVisitor {
type Value = RawEventAction;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("an event action map with a 'name' field")
}
fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<RawEventAction, A::Error> {
let mut name: Option<String> = None;
let mut status: Option<String> = None;
let mut from: Option<String> = None;
let mut to: Option<String> = None;
while let Some(key) = map.next_key::<String>()? {
match key.as_str() {
"name" => name = Some(map.next_value()?),
"status" => status = Some(map.next_value()?),
"from" => from = Some(map.next_value()?),
"to" => to = Some(map.next_value()?),
_ => {
let _ = map.next_value::<serde::de::IgnoredAny>()?;
}
}
}
let name = name.ok_or_else(|| de::Error::missing_field("name"))?;
Ok(match name.as_str() {
"created" => RawEventAction::Created {
status: status.ok_or_else(|| de::Error::missing_field("status"))?,
},
"status_changed" => RawEventAction::StatusChanged {
from: from.ok_or_else(|| de::Error::missing_field("from"))?,
to: to.ok_or_else(|| de::Error::missing_field("to"))?,
},
other => RawEventAction::Other(other.to_string()),
})
}
}
}
#[derive(Debug, Clone)]
pub struct RawEvent {
pub timestamp: crate::domain::model::temporal::timestamp::Timestamp,
pub action: RawEventAction,
}
impl<'de> serde::Deserialize<'de> for RawEvent {
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
raw_event_compat::deserialize(d)
}
}
pub mod raw_event_compat {
use super::{RawEvent, RawEventAction};
use crate::domain::model::temporal::timestamp::Timestamp;
use serde::de::{self, MapAccess, Visitor};
use serde::Deserializer;
use std::fmt;
pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<RawEvent, D::Error> {
d.deserialize_map(RawEventVisitor)
}
struct RawEventVisitor;
impl<'de> Visitor<'de> for RawEventVisitor {
type Value = RawEvent;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("an event map")
}
fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<RawEvent, A::Error> {
let mut timestamp: Option<Timestamp> = None;
let mut action_raw: Option<ActionRaw> = None;
let mut from_v1: Option<String> = None;
let mut to_v1: Option<String> = None;
while let Some(key) = map.next_key::<String>()? {
match key.as_str() {
"timestamp" => timestamp = Some(map.next_value()?),
"action" => action_raw = Some(map.next_value()?),
"from" => from_v1 = Some(map.next_value()?),
"to" => to_v1 = Some(map.next_value()?),
_ => {
let _ = map.next_value::<serde::de::IgnoredAny>()?;
}
}
}
let timestamp = timestamp.ok_or_else(|| de::Error::missing_field("timestamp"))?;
let action_raw = action_raw.ok_or_else(|| de::Error::missing_field("action"))?;
let action = match action_raw {
ActionRaw::V2(a) => a,
ActionRaw::V1(name) => match name.as_str() {
"created" => RawEventAction::Created {
status: from_v1.unwrap_or_default(),
},
"status_changed" => RawEventAction::StatusChanged {
from: from_v1.unwrap_or_default(),
to: to_v1.unwrap_or_default(),
},
other => RawEventAction::Other(other.to_string()),
},
};
Ok(RawEvent { timestamp, action })
}
}
enum ActionRaw {
V1(String),
V2(RawEventAction),
}
impl<'de> serde::Deserialize<'de> for ActionRaw {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
struct ActionRawVisitor;
impl<'de> Visitor<'de> for ActionRawVisitor {
type Value = ActionRaw;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("a string (v1) or a map (v2) for the action field")
}
fn visit_str<E: de::Error>(self, v: &str) -> Result<ActionRaw, E> {
Ok(ActionRaw::V1(v.to_string()))
}
fn visit_string<E: de::Error>(self, v: String) -> Result<ActionRaw, E> {
Ok(ActionRaw::V1(v))
}
fn visit_map<A: MapAccess<'de>>(self, map: A) -> Result<ActionRaw, A::Error> {
use serde::de::value::MapAccessDeserializer;
let action =
super::raw_event_action::deserialize(MapAccessDeserializer::new(map))?;
Ok(ActionRaw::V2(action))
}
}
d.deserialize_any(ActionRawVisitor)
}
}
}
pub struct EventLogSer<'a>(pub &'a crate::domain::model::event::EventLog);
impl Serialize for EventLogSer<'_> {
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeSeq;
let mut seq = s.serialize_seq(Some(self.0.len()))?;
for event in self.0.iter() {
seq.serialize_element(&EventSer(event))?;
}
seq.end()
}
}
struct EventSer<'a>(&'a crate::domain::model::event::Event);
impl Serialize for EventSer<'_> {
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
use serde::ser::SerializeMap;
let e = self.0;
let mut map = s.serialize_map(Some(2))?;
map.serialize_entry("timestamp", &e.timestamp)?;
map.serialize_entry("action", &e.action)?;
map.end()
}
}