phink_lib/cover/
trace.rs

1use serde_derive::{
2    Deserialize,
3    Serialize,
4};
5
6pub const COV_IDENTIFIER: &str = "COV=";
7#[derive(Clone, Default, Serialize, Debug, Deserialize)]
8pub struct CoverageTrace(pub Vec<u8>);
9
10impl From<Vec<u8>> for CoverageTrace {
11    fn from(vec: Vec<u8>) -> Self {
12        CoverageTrace(vec)
13    }
14}
15
16impl AsRef<[u8]> for CoverageTrace {
17    fn as_ref(&self) -> &[u8] {
18        self.0.as_slice()
19    }
20}
21
22impl CoverageTrace {
23    pub fn as_string(&self) -> String {
24        String::from_utf8_lossy(&self.0).to_string()
25    }
26
27    pub fn parse_coverage(&self) -> Vec<u64> {
28        let coverage_str = self.as_string();
29        let mut parsed = Vec::new();
30
31        for part in coverage_str.split_whitespace() {
32            if let Some(cov) = part.strip_prefix(COV_IDENTIFIER) {
33                if let Ok(value) = cov.parse::<u64>() {
34                    parsed.push(value);
35                }
36            }
37        }
38        parsed
39    }
40
41    pub fn remove_cov_from_trace(&self) -> String {
42        self.as_string()
43            .split_whitespace()
44            .filter(|&s| !s.starts_with(COV_IDENTIFIER))
45            .collect::<Vec<&str>>()
46            .join(" ")
47    }
48}
49#[cfg(test)]
50mod tests {
51    use super::*;
52
53    #[test]
54    fn test_parse_coverage_empty() {
55        let trace = CoverageTrace(vec![]);
56        assert_eq!(trace.parse_coverage(), Vec::<u64>::new());
57    }
58
59    #[test]
60    fn test_parse_coverage_with_valid_data() {
61        let data = "COV=10 COV=20 other_data COV=30".as_bytes().to_vec();
62        let trace = CoverageTrace(data);
63        assert_eq!(trace.parse_coverage(), vec![10, 20, 30]);
64    }
65
66    #[test]
67    fn test_parse_coverage_with_invalid_data() {
68        let data = "COV=10 COV=invalid COV=30".as_bytes().to_vec();
69        let trace = CoverageTrace(data);
70        assert_eq!(trace.parse_coverage(), vec![10, 30]);
71    }
72
73    #[test]
74    fn test_new_line() {
75        let data = "COV=10\nCOV=invalid\nCOV=30".as_bytes().to_vec();
76        let trace = CoverageTrace(data);
77        assert_eq!(trace.parse_coverage(), vec![10, 30]);
78    }
79
80    #[test]
81    fn test_remove_cov_from_trace() {
82        let data = "COV=10 other_data COV=20 more_data".as_bytes().to_vec();
83        let trace = CoverageTrace(data);
84        let cleaned = trace.remove_cov_from_trace();
85        assert_eq!(cleaned, "other_data more_data");
86    }
87
88    #[test]
89    fn test_yet_another_invalid() {
90        let data = "COV=10 other_data COV=20rzerze more_data"
91            .as_bytes()
92            .to_vec();
93        let trace = CoverageTrace(data);
94        let cleaned = trace.remove_cov_from_trace();
95        assert_eq!(cleaned, "other_data more_data");
96    }
97}