///|
pub struct ThemeProvenance {
path : String
layer : Int
source : String
} derive(Debug, Eq)
///|
pub fn ThemeProvenance::new(
path : String,
layer : Int,
source : String,
) -> ThemeProvenance {
{ path, layer, source }
}
///|
pub fn ThemeDocument::merge_layers(
layers : Array[ThemeDocument],
) -> ThemeDocument {
let tokens : Array[ThemeToken] = []
let provenance : Array[ThemeProvenance] = []
let aliases : Array[ThemeAlias] = []
for layer_index, layer in layers {
for link in layer.aliases {
if !aliases.any(fn(item) {
item.name.canonical() == link.name.canonical()
}) {
aliases.push(link)
}
}
for token in layer.tokens {
let path = token.path.canonical()
let existing_index = find_token_index(tokens, path)
match existing_index {
Some(index) => {
tokens[index] = token
provenance[index] = ThemeProvenance::new(
path,
layer_index,
"layer " + layer_index.to_string(),
)
}
None => {
tokens.push(token)
provenance.push(
ThemeProvenance::new(
path,
layer_index,
"layer " + layer_index.to_string(),
),
)
}
}
}
}
{ tokens, aliases, provenance }
}
///|
pub fn ThemeDocument::provenance(
self : ThemeDocument,
path : String,
) -> String? {
let wanted = TokenPath::from_string(path).canonical()
for item in self.provenance {
if item.path == wanted {
return Some(item.source)
}
}
None
}
///|
pub fn ThemeDocument::layer_for(self : ThemeDocument, path : String) -> Int? {
let wanted = TokenPath::from_string(path).canonical()
for item in self.provenance {
if item.path == wanted {
return Some(item.layer)
}
}
None
}
///|
pub fn ThemeDocument::with_source(
self : ThemeDocument,
source : String,
) -> ThemeDocument {
let provenance : Array[ThemeProvenance] = []
for token in self.tokens {
provenance.push(ThemeProvenance::new(token.path.canonical(), 0, source))
}
{ ..self, provenance, }
}
///|
pub fn ThemeDocument::override_token(
self : ThemeDocument,
token : ThemeToken,
source : String,
) -> ThemeDocument {
ThemeDocument::merge_layers([
self,
ThemeDocument::empty().add(token).with_source(source),
])
}
///|
fn find_token_index(tokens : Array[ThemeToken], path : String) -> Int? {
for i, token in tokens {
if token.path.canonical() == path {
return Some(i)
}
}
None
}