1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
use std::collections::HashMap; use regex::Regex; pub fn replace_named(src: &str, params: &HashMap<&str, String>) -> String { let mut parts: Vec<&str> = vec![]; let regex = Regex::new(r"\{([\w]+)\}").unwrap(); let matches: Vec<(usize,usize)> = regex .find_iter(src) .map(|m| (m.start(), m.end())) .collect(); let mut offset = 0usize; for (start, end) in matches.iter() { parts.push(&src[offset..*start]); let arg = &src[*start..*end]; let arg_name = &src[*start+1..*end-1]; match params.get(arg_name) { Some(s) => parts.push(s), None => parts.push(arg), } offset = *end; } if offset < src.len() { parts.push(&src[offset..src.len()]); } parts.join("") } #[test] fn test_replace() { let mut data = HashMap::new(); data.insert("name","lyf".to_string()); data.insert("id","123".to_string()); assert_eq!(replace_named("/path1/{name}/hello/{id}/res", &data), "/path1/lyf/hello/123/res"); assert_eq!(replace_named("/{name}/{id}", &data), "/lyf/123"); assert_eq!(replace_named("/{name}/{id}/", &data), "/lyf/123/"); assert_eq!(replace_named("{name}/{id}/", &data), "lyf/123/"); assert_eq!(replace_named("{name2}/{id}/", &data), "{name2}/123/"); assert_eq!(replace_named("/path/res", &data), "/path/res"); }