mod arity;
mod fields;
mod models;
mod procedures;
mod render;
#[cfg(test)]
mod test_support;
#[cfg(test)]
mod tests_attributes;
#[cfg(test)]
mod tests_models;
#[cfg(test)]
mod tests_procedures;
use cratestack_core::Schema;
use serde::Serialize;
pub(crate) use render::{render_human, render_json};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "snake_case")]
pub(crate) enum Severity {
Breaking,
Additive,
Internal,
}
impl Severity {
pub(crate) fn label(self) -> &'static str {
match self {
Severity::Breaking => "BREAKING",
Severity::Additive => "ADDITIVE",
Severity::Internal => "INTERNAL",
}
}
}
#[derive(Debug, Clone, Serialize)]
pub(crate) struct Change {
pub(crate) severity: Severity,
pub(crate) category: &'static str,
pub(crate) subject: String,
pub(crate) message: String,
}
#[derive(Debug, Clone, Default, Serialize)]
pub(crate) struct SchemaDiff {
pub(crate) changes: Vec<Change>,
}
impl SchemaDiff {
pub(crate) fn has_breaking(&self) -> bool {
self.changes
.iter()
.any(|change| change.severity == Severity::Breaking)
}
pub(crate) fn counts(&self) -> (usize, usize, usize) {
let mut counts = (0, 0, 0);
for change in &self.changes {
match change.severity {
Severity::Breaking => counts.0 += 1,
Severity::Additive => counts.1 += 1,
Severity::Internal => counts.2 += 1,
}
}
counts
}
}
pub(crate) fn diff_schemas(prev: &Schema, next: &Schema) -> SchemaDiff {
let mut changes = Vec::new();
models::diff_models(prev, next, &mut changes);
procedures::diff_procedures(prev, next, &mut changes);
SchemaDiff { changes }
}