diff --git a/src/filter.rs b/src/filter.rs index 56d4ba3..7425bd7 100644 --- a/src/filter.rs +++ b/src/filter.rs @@ -1,20 +1,13 @@ use std::str; -pub fn filter(block_list: &Vec, buf: &[u8]) -> String { +pub fn filter<'a>(block_list: &'a Vec, buf: &'a [u8]) -> Vec<&'a str> { let statsd_str = unsafe { str::from_utf8_unchecked(&buf) }; - let result_itr = statsd_str.split("\n").filter(|line| { - for prefix in block_list.iter() { - if line.starts_with(prefix) { - return false; - } - } - return true; - }); - - let result = result_itr.collect::>().join("\n"); - - return result; + statsd_str.split("\n") + .filter(|line| { + !block_list.iter().any(|prefix| line.starts_with(prefix)) + }) + .collect::>() } #[cfg(test)] @@ -25,7 +18,7 @@ mod tests { fn test_should_not_block_multi_metric() { let block_list = vec![String::from("notfoo"), String::from("otherfoo")]; let statsd_str_bytes = "foo:1|c\nfoo:2|c\nfoo:3|c".as_bytes(); - let result = filter(&block_list, &statsd_str_bytes); + let result = filter(&block_list, &statsd_str_bytes).join("\n"); assert_eq!("foo:1|c\nfoo:2|c\nfoo:3|c", result); } @@ -34,7 +27,7 @@ mod tests { fn test_should_not_block_single_metric() { let block_list = vec![String::from("notfoo"), String::from("otherfoo")]; let statsd_str_bytes = "foo:1|c".as_bytes(); - let result = filter(&block_list, &statsd_str_bytes); + let result = filter(&block_list, &statsd_str_bytes).join("\n"); assert_eq!("foo:1|c", result); } @@ -42,7 +35,7 @@ mod tests { fn test_should_block_completely_single_metric() { let block_list = vec![String::from("foo"), String::from("otherfoo")]; let statsd_str_bytes = "foo:1|c".as_bytes(); - let result = filter(&block_list, &statsd_str_bytes); + let result = filter(&block_list, &statsd_str_bytes).join("\n"); assert_eq!("", result); } @@ -50,7 +43,7 @@ mod tests { fn test_should_block_completely_multi_metric() { let block_list = vec![String::from("foo"), String::from("otherfoo")]; let statsd_str_bytes = "foo:1|c\nfoo:2|c\nfoo:3|c".as_bytes(); - let result = filter(&block_list, &statsd_str_bytes); + let result = filter(&block_list, &statsd_str_bytes).join("\n"); assert_eq!("", result); } @@ -58,7 +51,7 @@ mod tests { fn test_should_block_partially_multi_metric() { let block_list = vec![String::from("foo"), String::from("otherfoo")]; let statsd_str_bytes = "notfoo:1|c\nfoo:2|c\nnotfoo:3|c".as_bytes(); - let result = filter(&block_list, &statsd_str_bytes); + let result = filter(&block_list, &statsd_str_bytes).join("\n"); assert_eq!("notfoo:1|c\nnotfoo:3|c", result); } } diff --git a/src/server.rs b/src/server.rs index c4d276e..4012509 100644 --- a/src/server.rs +++ b/src/server.rs @@ -44,8 +44,9 @@ pub async fn run_server(config: Config) -> io::Result<()> { let target_addr_clone = target_addr.clone(); let blocklist_clone = blocklist.clone(); tokio::spawn(async move { - let filtered_string = filter(&blocklist_clone, &buf[..len]); - if filtered_string.len() > 0 { + let filtered_string_parts = filter(&blocklist_clone, &buf[..len]); + if !filtered_string_parts.is_empty() { + let filtered_string = filtered_string_parts.join("\n"); let len = sock_clone .send_to(filtered_string.as_bytes(), &*target_addr_clone) .await @@ -60,8 +61,9 @@ pub async fn run_server(config: Config) -> io::Result<()> { } }); } else { - let filtered_string = filter(&blocklist, &buf[..len]); - if filtered_string.len() > 0 { + let filtered_string_parts = filter(&blocklist, &buf[..len]); + if !filtered_string_parts.is_empty() { + let filtered_string = filtered_string_parts.join("\n"); let len = sock .send_to(filtered_string.as_bytes(), &*target_addr) .await