use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct CallableMessage {
strings: Vec<String>,
keys: Vec<String>,
}
impl CallableMessage {
pub fn new(strings: Vec<String>, keys: Vec<String>) -> Self {
Self { strings, keys }
}
pub fn invoke(&self, values: &HashMap<String, String>) -> String {
let mut result = self.strings[0].clone();
for (i, key) in self.keys.iter().enumerate() {
if let Some(value) = values.get(key) {
result.push_str(value);
}
if i + 1 < self.strings.len() {
result.push_str(&self.strings[i + 1]);
}
}
result
}
pub fn keys(&self) -> &[String] {
&self.keys
}
}
pub struct ParamMessage;
impl ParamMessage {
pub fn m1(s1: &str, k0: &str, s2: &str) -> CallableMessage {
CallableMessage::new(vec![s1.to_string(), s2.to_string()], vec![k0.to_string()])
}
pub fn m2(s1: &str, k0: &str, s2: &str, k1: &str, s3: &str) -> CallableMessage {
CallableMessage::new(
vec![s1.to_string(), s2.to_string(), s3.to_string()],
vec![k0.to_string(), k1.to_string()],
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_param_message_single_param_middle() {
let msg = CallableMessage::new(
vec!["My name is ".to_string(), ".".to_string()],
vec!["name".to_string()],
);
let mut values = HashMap::new();
values.insert("name".to_string(), "Foo".to_string());
assert_eq!(msg.invoke(&values), "My name is Foo.");
}
#[test]
fn test_param_message_single_param_start() {
let msg = CallableMessage::new(
vec!["".to_string(), " is my name.".to_string()],
vec!["name".to_string()],
);
let mut values = HashMap::new();
values.insert("name".to_string(), "Foo".to_string());
assert_eq!(msg.invoke(&values), "Foo is my name.");
}
#[test]
fn test_param_message_single_param_end() {
let msg = CallableMessage::new(
vec!["My name: ".to_string(), "".to_string()],
vec!["name".to_string()],
);
let mut values = HashMap::new();
values.insert("name".to_string(), "Foo".to_string());
assert_eq!(msg.invoke(&values), "My name: Foo");
}
#[test]
fn test_param_message_multiple_params() {
let msg = CallableMessage::new(
vec![
"My name is ".to_string(),
" and my age is ".to_string(),
".".to_string(),
],
vec!["name".to_string(), "age".to_string()],
);
let mut values = HashMap::new();
values.insert("name".to_string(), "Foo".to_string());
values.insert("age".to_string(), "34".to_string());
assert_eq!(msg.invoke(&values), "My name is Foo and my age is 34.");
}
#[test]
fn test_param_message_adjacent_params() {
let msg = CallableMessage::new(
vec![
"My username is ".to_string(),
"".to_string(),
".".to_string(),
],
vec!["name".to_string(), "age".to_string()],
);
let mut values = HashMap::new();
values.insert("name".to_string(), "Foo".to_string());
values.insert("age".to_string(), "34".to_string());
assert_eq!(msg.invoke(&values), "My username is Foo34.");
}
#[test]
fn test_param_message_missing_value() {
let msg = CallableMessage::new(
vec!["Hello ".to_string(), "!".to_string()],
vec!["name".to_string()],
);
let mut values = HashMap::new();
values.insert("other".to_string(), "Foo".to_string());
assert_eq!(msg.invoke(&values), "Hello !");
}
#[test]
fn test_param_message_keys() {
let msg = CallableMessage::new(
vec!["Test ".to_string(), "".to_string()],
vec!["key0".to_string()],
);
assert_eq!(msg.keys(), &["key0".to_string()]);
}
}