use serde_derive::Serialize;
use std::fmt::{Display, Error, Formatter};
#[derive(Debug, Serialize, Clone)]
pub struct Keyboard {
buttons: Vec<Vec<Button>>,
one_time: bool,
}
impl Default for Keyboard {
fn default() -> Self {
Self {
buttons: Vec::new(),
one_time: false,
}
}
}
impl Keyboard {
pub fn new(buttons: Vec<Vec<Button>>, one_time: bool) -> Self {
Self { buttons, one_time }
}
}
#[derive(Debug, Serialize, Clone)]
pub struct Button {
color: Color,
action: ButtonAction,
}
impl Default for Button {
fn default() -> Self {
Self {
color: Default::default(),
action: Default::default(),
}
}
}
impl Button {
pub fn new(label: &str, color: Color, payload: Option<String>) -> Self {
Self {
color,
action: ButtonAction {
label: label.into(),
payload,
..Default::default()
},
}
}
}
#[derive(Debug, Serialize, Clone)]
pub struct ButtonAction {
r#type: String,
label: String,
#[serde(skip_serializing_if = "Option::is_none")]
payload: Option<String>,
}
impl Default for ButtonAction {
fn default() -> Self {
Self {
r#type: "text".into(),
label: "Button".into(),
payload: None,
}
}
}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum Color {
Primary,
Default,
Negative,
Positive,
}
impl Default for Color {
fn default() -> Self {
Color::Default
}
}
impl Display for Color {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
f.write_str(match self {
Color::Primary => "primary",
Color::Default => "default",
Color::Negative => "negative",
Color::Positive => "positive",
})
}
}
impl From<&str> for Color {
fn from(s: &str) -> Self {
match s {
"primary" => Color::Primary,
"default" => Color::Default,
"negative" => Color::Negative,
"positive" => Color::Positive,
_ => panic!("unknown color: `{}`", s),
}
}
}
impl From<String> for Color {
fn from(s: String) -> Self {
s.as_str().into()
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn empty_keyboard() -> Result<(), serde_json::Error> {
let kbd = Keyboard::new(vec![], false);
assert_eq!(
serde_json::to_value(&kbd)?,
json!({
"one_time": false,
"buttons": [],
})
);
Ok(())
}
#[test]
fn keyboard() -> Result<(), serde_json::Error> {
let payload = serde_json::to_string(&json!({"payload": "json"}))?;
let kbd = Keyboard::new(
vec![
vec![
Button::new("1", Color::Default, None),
Button::new("2", Color::Primary, Some(payload.clone())),
],
vec![
Button::new("3", Color::Negative, None),
Button::new("4", Color::Positive, None),
],
],
true,
);
assert_eq!(
serde_json::to_value(&kbd)?,
json!({
"buttons":[
[
{"color":"default","action":{"type":"text","label":"1"}},
{"color":"primary","action":{"type":"text","label":"2","payload":payload}}
],
[
{"color":"negative","action":{"type":"text","label":"3"}},
{"color":"positive","action":{"type":"text","label":"4"}}
]
],
"one_time":true
})
);
Ok(())
}
}