oino_ui/extras/
key_hints.rs1use serde::{Deserialize, Serialize};
4
5use crate::node::{ActionId, Common, IntoNode, Node};
6
7#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct Hint {
11 pub keys: String,
13 pub label: String,
15 #[serde(default, skip_serializing_if = "Option::is_none")]
17 pub action: Option<ActionId>,
18}
19
20impl Hint {
21 #[must_use]
23 pub fn new(keys: impl Into<String>, label: impl Into<String>) -> Self {
24 Self {
25 keys: keys.into(),
26 label: label.into(),
27 action: None,
28 }
29 }
30
31 #[must_use]
33 pub fn with_action(
34 keys: impl Into<String>,
35 label: impl Into<String>,
36 action: impl Into<ActionId>,
37 ) -> Self {
38 Self {
39 keys: keys.into(),
40 label: label.into(),
41 action: Some(action.into()),
42 }
43 }
44}
45
46impl From<(&str, &str)> for Hint {
47 fn from((keys, label): (&str, &str)) -> Self {
48 Self::new(keys, label)
49 }
50}
51
52impl From<(&str, &str, &str)> for Hint {
53 fn from((keys, label, action): (&str, &str, &str)) -> Self {
54 Self::with_action(keys, label, action)
55 }
56}
57
58#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
60#[serde(rename_all = "camelCase")]
61pub struct KeyHints {
62 #[serde(flatten)]
64 pub common: Common,
65 pub hints: Vec<Hint>,
67}
68
69impl KeyHints {
70 #[must_use]
72 pub fn new(hints: impl IntoIterator<Item = impl Into<Hint>>) -> Self {
73 Self {
74 hints: hints.into_iter().map(Into::into).collect(),
75 ..Self::default()
76 }
77 }
78
79 #[must_use]
81 pub fn hint_action(mut self, keys: &str, action: impl Into<ActionId>) -> Self {
82 for hint in &mut self.hints {
83 if hint.keys == keys {
84 hint.action = Some(action.into());
85 break;
86 }
87 }
88 self
89 }
90}
91
92impl IntoNode for KeyHints {}
93impl From<KeyHints> for Node {
94 fn from(k: KeyHints) -> Self {
95 Node::KeyHints(k)
96 }
97}