///|
pub struct ThemeChange {
path : String
before : ThemeToken
after : ThemeToken
} derive(Debug, Eq)
///|
pub struct ThemeDiff {
added : Array[ThemeToken]
removed : Array[ThemeToken]
changed : Array[ThemeChange]
} derive(Debug, Eq)
///|
pub fn ThemeDiff::between(
before : ThemeDocument,
after : ThemeDocument,
) -> ThemeDiff {
let added : Array[ThemeToken] = []
let removed : Array[ThemeToken] = []
let changed : Array[ThemeChange] = []
for old in before.tokens {
match after.find(old.path.canonical()) {
None => removed.push(old)
Some(new) if old != new =>
changed.push(ThemeChange::{
path: old.path.canonical(),
before: old,
after: new,
})
Some(_) => ()
}
}
for new in after.tokens {
if before.find(new.path.canonical()) is None {
added.push(new)
}
}
{ added, removed, changed }
}
///|
pub fn ThemeDiff::is_empty(self : ThemeDiff) -> Bool {
self.added.length() == 0 &&
self.removed.length() == 0 &&
self.changed.length() == 0
}
///|
pub fn ThemeDiff::change_count(self : ThemeDiff) -> Int {
self.added.length() + self.removed.length() + self.changed.length()
}
///|
pub fn ThemeDiff::has_breaking_changes(self : ThemeDiff) -> Bool {
self.removed.length() > 0
}
///|
pub fn ThemeDiff::summary(self : ThemeDiff) -> String {
"added=" +
self.added.length().to_string() +
", removed=" +
self.removed.length().to_string() +
", changed=" +
self.changed.length().to_string()
}
///|
pub fn ThemeDiff::to_markdown(self : ThemeDiff) -> String {
let lines : Array[String] = [
"## Theme diff",
"",
"Summary: " + self.summary(),
"",
]
if self.added.length() > 0 {
lines.push("### Added")
for token in self.added {
lines.push("- `" + token.path.canonical() + "`")
}
lines.push("")
}
if self.removed.length() > 0 {
lines.push("### Removed")
for token in self.removed {
lines.push("- `" + token.path.canonical() + "`")
}
lines.push("")
}
if self.changed.length() > 0 {
lines.push("### Changed")
for change in self.changed {
lines.push(
"- `" +
change.path +
"`: " +
theme_value_display(change.before.value) +
" → " +
theme_value_display(change.after.value),
)
}
}
lines.join("\n")
}
///|
pub fn ThemeDiff::migration_steps(self : ThemeDiff) -> Array[String] {
let steps : Array[String] = []
for token in self.added {
steps.push("add token " + token.path.canonical())
}
for token in self.removed {
steps.push("remove token " + token.path.canonical())
}
for change in self.changed {
steps.push("review change " + change.path)
}
steps
}
///|
pub fn BrandBook::diff_theme(self : BrandBook, other : BrandBook) -> ThemeDiff {
ThemeDiff::between(self.theme_document(), other.theme_document())
}