use serde::{Deserialize, Serialize};
use crate::node::{ActionId, Common, IntoNode, Node};
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Hint {
pub keys: String,
pub label: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub action: Option<ActionId>,
}
impl Hint {
#[must_use]
pub fn new(keys: impl Into<String>, label: impl Into<String>) -> Self {
Self {
keys: keys.into(),
label: label.into(),
action: None,
}
}
#[must_use]
pub fn with_action(
keys: impl Into<String>,
label: impl Into<String>,
action: impl Into<ActionId>,
) -> Self {
Self {
keys: keys.into(),
label: label.into(),
action: Some(action.into()),
}
}
}
impl From<(&str, &str)> for Hint {
fn from((keys, label): (&str, &str)) -> Self {
Self::new(keys, label)
}
}
impl From<(&str, &str, &str)> for Hint {
fn from((keys, label, action): (&str, &str, &str)) -> Self {
Self::with_action(keys, label, action)
}
}
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct KeyHints {
#[serde(flatten)]
pub common: Common,
pub hints: Vec<Hint>,
}
impl KeyHints {
#[must_use]
pub fn new(hints: impl IntoIterator<Item = impl Into<Hint>>) -> Self {
Self {
hints: hints.into_iter().map(Into::into).collect(),
..Self::default()
}
}
#[must_use]
pub fn hint_action(mut self, keys: &str, action: impl Into<ActionId>) -> Self {
for hint in &mut self.hints {
if hint.keys == keys {
hint.action = Some(action.into());
break;
}
}
self
}
}
impl IntoNode for KeyHints {}
impl From<KeyHints> for Node {
fn from(k: KeyHints) -> Self {
Node::KeyHints(k)
}
}