///|
pub struct TokenQuery {
kind : TokenKind?
prefix : String
text : String
value : String
} derive(Debug, Eq)
///|
pub fn TokenQuery::empty() -> TokenQuery {
{ kind: None, prefix: "", text: "", value: "" }
}
///|
pub fn TokenQuery::parse(text : String) -> TokenQuery {
let query = TokenQuery::empty()
let mut result = query
for part in text.split(" ") {
let item = part.trim().to_owned()
if item == "" {
continue
}
match query_key_value(item) {
Some((key, value)) =>
match key {
"kind" => result = { ..result, kind: token_kind_from_name(value) }
"prefix" =>
result = {
..result,
prefix: TokenPath::from_string(value).canonical(),
}
"text" | "name" => result = { ..result, text: value }
"value" => result = { ..result, value, }
_ => ()
}
None => result = { ..result, text: item }
}
}
result
}
///|
pub fn TokenQuery::with_kind(self : TokenQuery, kind : TokenKind) -> TokenQuery {
{ ..self, kind: Some(kind) }
}
///|
pub fn TokenQuery::with_prefix(
self : TokenQuery,
prefix : String,
) -> TokenQuery {
{ ..self, prefix: TokenPath::from_string(prefix).canonical() }
}
///|
pub fn TokenQuery::with_text(self : TokenQuery, text : String) -> TokenQuery {
{ ..self, text, }
}
///|
pub fn TokenCatalog::query(
self : TokenCatalog,
query : TokenQuery,
) -> Array[CatalogEntry] {
let result : Array[CatalogEntry] = []
for entry in self.entries {
let kind_ok = match query.kind {
Some(kind) => entry.kind == kind
None => true
}
let prefix_ok = query.prefix == "" ||
entry.path == query.prefix ||
entry.path.has_prefix(query.prefix + ".")
let text_ok = query.text == "" ||
ascii_lower(entry.path).contains(ascii_lower(query.text)) ||
ascii_lower(entry.description).contains(ascii_lower(query.text))
let value_ok = query.value == "" ||
theme_value_display(entry.value).contains(query.value)
if kind_ok && prefix_ok && text_ok && value_ok {
result.push(entry)
}
}
result
}
///|
fn query_key_value(text : String) -> (String, String)? {
for i, ch in text {
if ch == '=' {
return Some(
(
substring_owned(text, 0, i),
substring_owned(text, i + 1, text.length()),
),
)
}
}
None
}
///|
fn token_kind_from_name(text : String) -> TokenKind? {
match normalize_identifier(text) {
"color" | "colors" => Some(Color)
"number" | "size" => Some(Number)
"text" | "string" => Some(Text)
"boolean" | "bool" => Some(Boolean)
_ => None
}
}