use super::*;
pub(crate) fn label_of(inst: &ResolvedInst) -> Option<String> {
inst.label.clone().filter(|t| !t.is_empty()).or_else(|| {
inst.children
.iter()
.find(|c| c.kind == NodeKind::Text)
.and_then(|c| c.label.as_deref())
.filter(|t| !t.is_empty())
.map(str::to_string)
})
}
pub(crate) fn fill_color(attrs: &AttrMap) -> Option<ResolvedValue> {
real_color(attrs.get("fill"))
}
pub(super) fn outline(attrs: &AttrMap) -> Option<(ResolvedValue, f64)> {
real_color(attrs.get("stroke")).map(|c| (c, attrs.number("stroke-width").unwrap_or(1.5)))
}
pub(crate) fn fill_outline(attrs: &AttrMap, fill: &ResolvedValue) -> Option<(ResolvedValue, f64)> {
let width = attrs.number("stroke-width").unwrap_or(1.5);
match attrs.get("stroke") {
Some(ResolvedValue::Ident(s)) if s == "none" => None,
Some(ResolvedValue::Ident(s)) if s == "auto" => Some((palette::deepen(fill), width)),
other => match real_color(other) {
Some(c) => Some((c, width)),
None => Some((palette::deepen(fill), width)),
},
}
}
pub(super) fn real_color(v: Option<&ResolvedValue>) -> Option<ResolvedValue> {
match v {
Some(ResolvedValue::Ident(s)) if s == "none" => None,
Some(ResolvedValue::LiveVar { name, .. }) if name == "stroke" || name == "fill" => None,
Some(other) => Some(other.clone()),
None => None,
}
}
pub(crate) fn live(name: &str) -> ResolvedValue {
ResolvedValue::LiveVar {
name: name.to_string(),
raw: false,
}
}
pub(super) fn muted() -> ResolvedValue {
live("muted")
}
pub(super) fn clone_grid(g: &Grid) -> Grid {
match g {
Grid::Default => Grid::Default,
Grid::Off => Grid::Off,
Grid::Color(c) => Grid::Color(c.clone()),
}
}
pub(super) fn numbers(items: &[ResolvedValue], span: Span) -> Result<Vec<f64>, Error> {
items.iter().map(|it| number(it, span)).collect()
}
pub(super) fn number(v: &ResolvedValue, span: Span) -> Result<f64, Error> {
v.as_number()
.ok_or_else(|| Error::at(span, "'data' values must be numbers"))
}