///|
/// A typed event wrapper. The encoder is explicit so MoonEvent can stay small
/// and avoid forcing a JSON dependency on users.
pub(all) struct TypedEvent[A] {
  name : String
  topic : String
  value : A
  tags : Array[String]
  priority : Int
  correlation_id : String
  encode : (A) -> String
}

///|
pub fn[A] TypedEvent::new(
  name : String,
  value : A,
  encode : (A) -> String,
  topic? : String = "",
  tags? : Array[String] = [],
  priority? : Int = 0,
  correlation_id? : String = "",
) -> TypedEvent[A] {
  { name, topic, value, tags, priority, correlation_id, encode }
}

///|
pub fn[A] TypedEvent::to_event(self : TypedEvent[A]) -> Event {
  Event::new(
    self.name,
    topic=self.topic,
    payload=(self.encode)(self.value),
    tags=self.tags,
    priority=self.priority,
    correlation_id=self.correlation_id,
  )
}