///|
fn optional_text_json(value : String?) -> Json {
match value {
Some(text) => Json::string(text)
None => Json::null()
}
}
///|
fn optional_instant_json(value : Int64?) -> Json {
match value {
Some(instant) => Json::string(format_instant(instant))
None => Json::null()
}
}
///|
fn span_json(span : Span) -> Json {
let fields : Map[String, Json] = Map([])
fields["from"] = Json::string(format_instant(span.start))
fields["to"] = optional_instant_json(span.end)
Json::object(fields)
}
///|
pub fn WindowChange::to_json(self : WindowChange) -> Json {
let fields : Map[String, Json] = Map([])
fields["valid"] = span_json(self.valid)
fields["before"] = optional_text_json(self.before)
fields["after"] = optional_text_json(self.after)
Json::object(fields)
}
///|
pub fn KeyChangeReport::to_json(self : KeyChangeReport) -> Json {
let fragments : Array[Json] = []
for change in self.fragments {
fragments.push(change.to_json())
}
let fields : Map[String, Json] = Map([])
fields["key"] = Json::string(self.key)
fields["fragments"] = Json::array(fragments)
Json::object(fields)
}
///|
/// Versioned JSON evidence for downstream dashboards or review workflows.
/// All 64-bit instants are encoded as decimal strings so JavaScript consumers
/// cannot silently round them. A `null` value denotes absence or withdrawal
/// according to the corresponding before/after side of the change.
pub fn ChangeReport::to_json(self : ChangeReport) -> Json {
let entries : Array[Json] = []
for entry in self.entries {
entries.push(entry.to_json())
}
let fields : Map[String, Json] = Map([])
fields["schemaVersion"] = Json::number(1.0)
fields["validWindow"] = span_json(self.bounds)
fields["beforeKnown"] = Json::string(format_instant(self.before_known))
fields["afterKnown"] = Json::string(format_instant(self.after_known))
fields["keysExamined"] = Json(self.keys_examined)
fields["keysChanged"] = Json(self.entries.length())
fields["fragmentCount"] = Json(self.fragments)
fields["entries"] = Json::array(entries)
Json::object(fields)
}
///|
pub fn ChangeReport::to_json_string(self : ChangeReport) -> String {
self.to_json().stringify()
}
///|
pub fn MatrixCell::to_json(self : MatrixCell) -> Json {
let fields : Map[String, Json] = Map([])
fields["validAt"] = Json::string(format_instant(self.valid_at))
fields["knownAt"] = Json::string(format_instant(self.known_at))
fields["state"] = Json::string(
match self.source {
None => "unclaimed"
Some(revision) =>
if revision.value is None {
"withdrawn"
} else {
"assigned"
}
},
)
fields["value"] = optional_text_json(self.value())
fields["sourceSequence"] = match self.source {
Some(revision) => Json(revision.sequence)
None => Json::null()
}
Json::object(fields)
}
///|
/// Export a sampled matrix in the same row-major order as `cell` access.
pub fn TemporalMatrix::to_json(self : TemporalMatrix) -> Json {
let valid_samples : Array[Json] = []
for instant in self.valid_samples {
valid_samples.push(Json::string(format_instant(instant)))
}
let knowledge_samples : Array[Json] = []
for instant in self.knowledge_samples {
knowledge_samples.push(Json::string(format_instant(instant)))
}
let cells : Array[Json] = []
for cell in self.cells {
cells.push(cell.to_json())
}
let fields : Map[String, Json] = Map([])
fields["schemaVersion"] = Json::number(1.0)
fields["key"] = Json::string(self.key)
fields["validSamples"] = Json::array(valid_samples)
fields["knowledgeSamples"] = Json::array(knowledge_samples)
fields["cells"] = Json::array(cells)
Json::object(fields)
}
///|
pub fn TemporalMatrix::to_json_string(self : TemporalMatrix) -> String {
self.to_json().stringify()
}