use sim_kernel::{CapabilityName, Expr, Symbol};
use sim_lib_scene::node;
use crate::universal_view::universal_regions;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Mode {
Household,
Builder,
Systems,
}
impl Mode {
pub fn from_name(name: &str) -> Option<Self> {
match name {
"household" => Some(Mode::Household),
"builder" => Some(Mode::Builder),
"systems" => Some(Mode::Systems),
_ => None,
}
}
pub fn symbol(self) -> Symbol {
Symbol::new(match self {
Mode::Household => "household",
Mode::Builder => "builder",
Mode::Systems => "systems",
})
}
pub fn depth(self) -> usize {
match self {
Mode::Household => 2,
Mode::Builder => 3,
Mode::Systems => 4,
}
}
}
pub fn universal_scene(value: &Expr, mode: Mode) -> Expr {
let mut regions = universal_regions(value);
regions.truncate(mode.depth());
node(
"stack",
vec![
("id", Expr::Symbol(Symbol::new("universal"))),
("dir", Expr::Symbol(Symbol::new("column"))),
("mode", Expr::Symbol(mode.symbol())),
("children", Expr::List(regions)),
],
)
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Exposure {
Shown,
ConfirmationGated,
Absent,
}
pub fn action_exposure(
required: &[CapabilityName],
granted: impl Fn(&CapabilityName) -> bool,
dangerous: bool,
mode: Mode,
) -> Exposure {
if !required.iter().all(&granted) {
return Exposure::Absent;
}
if dangerous {
return match mode {
Mode::Household => Exposure::Absent,
_ => Exposure::ConfirmationGated,
};
}
Exposure::Shown
}
pub fn denied_scene(reason: &str) -> Expr {
node(
"box",
vec![
("role", Expr::Symbol(Symbol::new("denied"))),
(
"children",
Expr::List(vec![
node(
"badge",
vec![
("status", Expr::Symbol(Symbol::new("error"))),
("label", Expr::String("denied".to_owned())),
],
),
node("text", vec![("text", Expr::String(reason.to_owned()))]),
]),
),
],
)
}
pub fn readonly_scene(value: &Expr, mode: Mode) -> Expr {
node(
"stack",
vec![
("role", Expr::Symbol(Symbol::new("readonly"))),
("dir", Expr::Symbol(Symbol::new("column"))),
(
"children",
Expr::List(vec![
node(
"badge",
vec![
("status", Expr::Symbol(Symbol::new("info"))),
("label", Expr::String("read-only".to_owned())),
],
),
universal_scene(value, mode),
]),
),
],
)
}