fret_runtime/window_command_gating/
snapshot.rs1use std::collections::HashMap;
3use std::sync::Arc;
4
5use crate::{CommandId, CommandMeta, CommandScope, InputContext, WhenExpr};
6
7#[derive(Debug, Default, Clone)]
11pub struct WindowCommandGatingSnapshot {
12 input_ctx: InputContext,
13 key_contexts: Vec<Arc<str>>,
14 enabled_overrides: HashMap<CommandId, bool>,
15 action_availability: Option<Arc<HashMap<CommandId, bool>>>,
16}
17
18impl WindowCommandGatingSnapshot {
19 pub fn new(input_ctx: InputContext, enabled_overrides: HashMap<CommandId, bool>) -> Self {
20 Self {
21 input_ctx,
22 key_contexts: Vec::new(),
23 enabled_overrides,
24 action_availability: None,
25 }
26 }
27
28 pub fn input_ctx(&self) -> &InputContext {
29 &self.input_ctx
30 }
31
32 pub fn key_contexts(&self) -> &[Arc<str>] {
33 self.key_contexts.as_slice()
34 }
35
36 pub fn with_input_ctx(mut self, input_ctx: InputContext) -> Self {
37 self.input_ctx = input_ctx;
38 self
39 }
40
41 pub fn with_key_contexts(mut self, key_contexts: Vec<Arc<str>>) -> Self {
42 self.key_contexts = key_contexts;
43 self
44 }
45
46 pub fn enabled_overrides(&self) -> &HashMap<CommandId, bool> {
47 &self.enabled_overrides
48 }
49
50 pub fn action_availability(&self) -> Option<&HashMap<CommandId, bool>> {
51 self.action_availability.as_deref()
52 }
53
54 pub fn is_action_available(&self, command: &CommandId) -> Option<bool> {
59 self.action_availability
60 .as_ref()
61 .and_then(|map| map.get(command).copied())
62 }
63
64 pub fn with_action_availability(
65 mut self,
66 action_availability: Option<Arc<HashMap<CommandId, bool>>>,
67 ) -> Self {
68 self.action_availability = action_availability;
69 self
70 }
71
72 pub fn is_enabled_for_meta(
73 &self,
74 command: &CommandId,
75 scope: CommandScope,
76 when: Option<&WhenExpr>,
77 ) -> bool {
78 if scope == CommandScope::Widget
79 && let Some(map) = self.action_availability.as_ref()
80 && let Some(is_available) = map.get(command).copied()
81 && !is_available
82 {
83 return false;
84 }
85 if when.is_some_and(|w| !w.eval_with_key_contexts(&self.input_ctx, &self.key_contexts)) {
86 return false;
87 }
88 self.enabled_overrides.get(command).copied().unwrap_or(true)
89 }
90
91 pub fn is_enabled_for_command(&self, command: &CommandId, meta: &CommandMeta) -> bool {
92 self.is_enabled_for_meta(command, meta.scope, meta.when.as_ref())
93 }
94}