///|
pub(all) struct SchemaCompatibility {
missing : Array[String]
incompatible : Array[String]
extra : Array[String]
}
///|
pub fn SchemaCompatibility::compatible(self : SchemaCompatibility) -> Bool {
self.missing.is_empty() && self.incompatible.is_empty()
}
///|
/// Exact typed consumer contract, independent of field order. No widening/casts.
pub fn Schema::check_contract(
self : Schema,
required : Schema,
) -> SchemaCompatibility {
let missing : Array[String] = []
let incompatible : Array[String] = []
let extra : Array[String] = []
let wanted : Map[String, Kind] = Map([])
for column in required.columns {
wanted[column.name] = column.kind
}
for column in required.columns {
match self.indexes.get(column.name) {
None => missing.push(column.name)
Some(i) =>
if self.columns[i].kind != column.kind {
incompatible.push(column.name)
}
}
}
for column in self.columns {
if !wanted.contains(column.name) {
extra.push(column.name)
}
}
{ missing, incompatible, extra, }
}