1use anyhow::{Error, Result};
2
3pub fn validate_interpolation_places_count(format: &String, params_len: usize) -> Result<()> {
4 validate_interpolation_places_on_custom_pattern(format, params_len, "{}")
5}
6
7pub fn validate_interpolation_places_on_custom_pattern(
8 format: &String,
9 params_len: usize,
10 custom_pattern: &str,
11) -> Result<()> {
12 let splitted = format.split(custom_pattern).into_iter();
13 let places_to_interpolate = Vec::from_iter(splitted).len();
14
15 if places_to_interpolate - 1 == params_len {
16 Ok(())
17 } else {
18 Err(Error::msg(format!(
19 "
20 \n Number of places to interpolate doesn't match with number of args provided.
21 Expected {}
22 Received {}
23 ",
24 places_to_interpolate - 1,
25 params_len
26 )))
27 }
28}
29
30pub fn interpolate(format: &String, values: Vec<String>) -> Result<String> {
31 interpolate_on_custom_val(format, values, "{}")
32}
33
34pub fn interpolate_on_custom_val(
35 format: &String,
36 values: Vec<String>,
37 interpolate_on: &str,
38) -> Result<String> {
39 let splitted = format.split(interpolate_on);
40 let appended: Vec<String> = splitted
41 .into_iter()
42 .enumerate()
43 .map(|(i, x)| {
44 if i >= values.len() {
45 return x.to_owned();
46 }
47 return x.to_owned() + &values[i];
48 })
49 .collect();
50
51 Ok(appended.join(""))
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn test_interpolate_no_placeholders() {
60 let format = String::from("Hello, world!");
61 let values = vec![];
62 let result = interpolate(&format, values);
63 assert!(result.is_ok());
64 assert_eq!(result.unwrap(), "Hello, world!");
65 }
66
67 #[test]
68 fn test_interpolate_single_placeholder() {
69 let format = String::from("Hello, {}!");
70 let values = vec![String::from("world")];
71 let result = interpolate(&format, values);
72 assert!(result.is_ok());
73 assert_eq!(result.unwrap(), "Hello, world!");
74 }
75
76 #[test]
77 fn test_interpolate_multiple_placeholders() {
78 let format = String::from("Hello, {}, you are {} years old.");
79 let values = vec![String::from("John"), String::from("30")];
80 let result = interpolate(&format, values);
81 assert!(result.is_ok());
82 assert_eq!(result.unwrap(), "Hello, John, you are 30 years old.");
83 }
84
85 #[test]
86 fn test_interpolate_not_enough_values() {
87 let format = String::from("Hello, {}!");
88 let values: Vec<String> = vec![];
89 let result = validate_interpolation_places_count(&format, values.len());
90 assert!(result.is_err());
91 }
92
93 #[test]
94 fn test_interpolate_too_many_values() {
95 let format = String::from("Hello, {}!");
96 let values = vec![String::from("world"), String::from("extra")];
97 let result = validate_interpolation_places_count(&format, values.len());
98 assert!(result.is_err());
99 }
100}