///|
pub(all) enum Edit {
  Set(String, String, String)
  SetAt(String, String, Int, String)
  Insert(String, String, String)
  Remove(String, String)
  RemoveAt(String, String, Int)
} derive(Eq, Debug)

///|
pub(all) struct EditFailure {
  index : Int
  diagnostic : Diagnostic
} derive(Eq, Debug)

///|
/// Sequential edits against freshly parsed snapshots. Error returns no partial doc.
pub fn Document::apply(
  self : Document,
  edits : Array[Edit],
) -> Result[Document, EditFailure] {
  let mut current = self
  for i, edit in edits {
    let result = match edit {
      Set(s, k, v) => current.set(s, k, v)
      SetAt(s, k, n, v) => current.set_at(s, k, n, v)
      Insert(s, k, v) => current.insert(s, k, v)
      Remove(s, k) => current.remove(s, k)
      RemoveAt(s, k, n) => current.remove_at(s, k, n)
    }
    match result {
      Ok(next) => current = next
      Err(diagnostic) => return Err({ index: i, diagnostic })
    }
  }
  Ok(current)
}