1use glib::{prelude::*, Variant, VariantTy, VariantType};
4
5use crate::{ActionMap, SimpleAction};
6
7#[doc(alias = "GActionEntry")]
8pub struct ActionEntry<O>
9where
10 O: IsA<ActionMap>,
11{
12 name: String,
13 parameter_type: Option<VariantType>,
14 state: Option<Variant>,
15 #[allow(clippy::type_complexity)]
16 pub(crate) activate: Option<Box<dyn Fn(&O, &SimpleAction, Option<&Variant>) + 'static>>,
17 #[allow(clippy::type_complexity)]
18 pub(crate) change_state: Option<Box<dyn Fn(&O, &SimpleAction, Option<&Variant>) + 'static>>,
19}
20
21impl<O> ActionEntry<O>
22where
23 O: IsA<ActionMap>,
24{
25 pub fn name(&self) -> &str {
26 &self.name
27 }
28
29 pub fn parameter_type(&self) -> Option<&VariantTy> {
30 self.parameter_type.as_deref()
31 }
32
33 pub fn state(&self) -> Option<&Variant> {
34 self.state.as_ref()
35 }
36
37 pub fn builder(name: &str) -> ActionEntryBuilder<O> {
38 ActionEntryBuilder::new(name)
39 }
40}
41
42impl<O> std::fmt::Debug for ActionEntry<O>
43where
44 O: IsA<ActionMap>,
45{
46 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47 f.debug_struct("ActionEntry")
48 .field("name", &self.name())
49 .field("parameter_type", &self.parameter_type())
50 .field("state", &self.state())
51 .finish()
52 }
53}
54
55#[derive(Debug)]
56pub struct ActionEntryBuilder<O>(ActionEntry<O>)
57where
58 O: IsA<ActionMap>;
59
60impl<O> ActionEntryBuilder<O>
61where
62 O: IsA<ActionMap>,
63{
64 pub fn new(name: &str) -> Self {
65 Self(ActionEntry {
66 name: name.to_owned(),
67 parameter_type: Default::default(),
68 state: Default::default(),
69 activate: Default::default(),
70 change_state: Default::default(),
71 })
72 }
73
74 pub fn parameter_type(mut self, parameter_type: Option<&VariantTy>) -> Self {
75 self.0.parameter_type = parameter_type.map(|vt| vt.to_owned());
76 self
77 }
78
79 pub fn state(mut self, state: Variant) -> Self {
80 self.0.state = Some(state);
81 self
82 }
83
84 pub fn activate<F: Fn(&O, &SimpleAction, Option<&Variant>) + 'static>(
85 mut self,
86 callback: F,
87 ) -> Self {
88 self.0.activate = Some(Box::new(callback));
89 self
90 }
91
92 pub fn change_state<F: Fn(&O, &SimpleAction, Option<&Variant>) + 'static>(
93 mut self,
94 callback: F,
95 ) -> Self {
96 self.0.change_state = Some(Box::new(callback));
97 self
98 }
99
100 pub fn build(self) -> ActionEntry<O> {
101 self.0
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108 use crate::prelude::*;
109
110 #[test]
111 fn action_entry() {
112 let app = crate::Application::new(None, Default::default());
113
114 app.add_action_entries(vec![
115 ActionEntry::builder("close")
116 .activate(move |_app, _, _| {
117 })
119 .build(),
120 ActionEntry::builder("enable")
121 .state(true.to_variant())
122 .change_state(move |_app, _, _| {
123 })
125 .build(),
126 ]);
127 assert!(app.lookup_action("close").is_some());
128 assert!(app.lookup_action("enable").is_some());
129 }
130}