use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum CompatibilityLevel {
Identical,
BackwardCompatible,
ForwardCompatible,
ConditionallyCompatible,
Incompatible,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum ChangeCategory {
Metadata,
Interface,
Type,
Semantic,
Rule,
Lineage,
Extension,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ComparisonScope {
#[serde(default = "default_true")]
pub interfaces: bool,
#[serde(default = "default_true")]
pub types: bool,
#[serde(default = "default_true")]
pub semantics: bool,
#[serde(default = "default_true")]
pub lineage: bool,
#[serde(default = "default_true")]
pub metadata: bool,
#[serde(default = "default_true")]
pub extensions: bool,
}
const fn default_true() -> bool {
true
}
impl ComparisonScope {
#[must_use]
pub const fn all() -> Self {
Self {
interfaces: true,
types: true,
semantics: true,
lineage: true,
metadata: true,
extensions: true,
}
}
pub fn from_tokens(tokens: &[String]) -> Result<Self, Vec<String>> {
Self::from_tokens_strict(tokens)
}
pub fn from_tokens_strict(tokens: &[String]) -> Result<Self, Vec<String>> {
if tokens.is_empty() {
return Ok(Self::all());
}
let mut scope = Self {
interfaces: false,
types: false,
semantics: false,
lineage: false,
metadata: false,
extensions: false,
};
let mut invalid = Vec::new();
for token in tokens {
match token.as_str() {
"interfaces" => scope.interfaces = true,
"types" => scope.types = true,
"semantics" => scope.semantics = true,
"lineage" => scope.lineage = true,
"metadata" => scope.metadata = true,
"extensions" => scope.extensions = true,
"all" => return Ok(Self::all()),
other => invalid.push(other.to_string()),
}
}
if !invalid.is_empty() {
return Err(invalid);
}
if !scope.interfaces
&& !scope.types
&& !scope.semantics
&& !scope.lineage
&& !scope.metadata
&& !scope.extensions
{
return Err(vec!["no valid scope aspects specified".into()]);
}
Ok(scope)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum DiffKind {
Neutral,
Additive,
Breaking,
Conditional,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AspectResult {
pub aspect: String,
pub compatible: bool,
pub message: String,
}