///|
fn escape_json(value : String) -> String {
  value.replace(old="\\", new="\\\\").replace(old="\"", new="\\\"")
}

///|
pub fn ClockEntry::to_json(self : ClockEntry) -> String {
  "{\"node\":\"" +
  escape_json(self.node) +
  "\",\"counter\":" +
  self.counter.to_string() +
  "}"
}

///|
pub fn VectorClock::to_json(self : VectorClock) -> String {
  let mut body = ""
  for i = 0; i < self.entries.length(); i = i + 1 {
    if i > 0 {
      body = body + ","
    }
    body = body + self.entries[i].to_json()
  }
  "{\"entries\":[" + body + "]}"
}

///|
pub fn CausalEvent::to_json(self : CausalEvent) -> String {
  "{\"id\":\"" +
  escape_json(self.id) +
  "\",\"origin\":\"" +
  escape_json(self.origin) +
  "\",\"payload\":\"" +
  escape_json(self.payload) +
  "\",\"clock\":" +
  self.clock.to_json() +
  "}"
}

///|
pub fn CausalPair::to_json(self : CausalPair) -> String {
  "{\"left\":\"" +
  escape_json(self.left) +
  "\",\"right\":\"" +
  escape_json(self.right) +
  "\",\"order\":\"" +
  self.order.name() +
  "\"}"
}

///|
pub fn CausalBuffer::to_json(self : CausalBuffer) -> String {
  "{\"delivered\":" +
  self.delivered.to_json() +
  ",\"pending\":" +
  self.pending.length().to_string() +
  ",\"max_pending\":" +
  self.max_pending.to_string() +
  ",\"dropped\":" +
  self.dropped.to_string() +
  "}"
}