use crate::domain::channel_events::InteractionButtons;
pub fn to_action_row(buttons: &InteractionButtons) -> serde_json::Value {
let discord_buttons: Vec<serde_json::Value> = buttons
.buttons
.iter()
.map(|btn| {
let style = button_style(&btn.id);
serde_json::json!({
"type": 2,
"style": style,
"custom_id": btn.id,
"label": btn.label,
})
})
.collect();
serde_json::json!({
"type": 1,
"components": discord_buttons,
})
}
fn button_style(id: &str) -> u8 {
let lower = id.to_lowercase();
if lower.contains("allow") || lower.contains("yes") {
1 } else if lower.contains("deny") || lower.contains("no") {
4 } else {
2 }
}
pub fn to_components_value(buttons: &InteractionButtons) -> serde_json::Value {
serde_json::json!([to_action_row(buttons)])
}
#[cfg(test)]
mod tests {
use super::*;
use crate::domain::channel_events::Button;
fn sample_buttons() -> InteractionButtons {
InteractionButtons {
prompt_text: "Continue?".into(),
buttons: vec![
Button {
id: "allow".into(),
label: "Yes".into(),
},
Button {
id: "deny".into(),
label: "No".into(),
},
Button {
id: "maybe".into(),
label: "Maybe".into(),
},
],
}
}
#[test]
fn action_row_structure() {
let row = to_action_row(&sample_buttons());
assert_eq!(row["type"], 1);
let components = row["components"].as_array().expect("components is array");
assert_eq!(components.len(), 3);
assert_eq!(components[0]["style"], 1);
assert_eq!(components[0]["custom_id"], "allow");
assert_eq!(components[0]["label"], "Yes");
assert_eq!(components[1]["style"], 4);
assert_eq!(components[2]["style"], 2);
}
#[test]
fn to_components_wraps_in_array() {
let val = to_components_value(&sample_buttons());
let arr = val.as_array().expect("top-level is array");
assert_eq!(arr.len(), 1);
assert_eq!(arr[0]["type"], 1);
}
#[test]
fn button_style_cases() {
assert_eq!(button_style("allow"), 1);
assert_eq!(button_style("yes_confirm"), 1);
assert_eq!(button_style("deny"), 4);
assert_eq!(button_style("no_way"), 4);
assert_eq!(button_style("other"), 2);
}
}