debian_analyzer/
transition.rs

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use crate::benfile::{read_benfile, Assignment, Expr};

#[derive(Debug, Default)]
pub struct Transition {
    pub title: Option<String>,
    pub is_good: Option<Expr>,
    pub is_bad: Option<Expr>,
    pub is_affected: Option<Expr>,
    pub notes: Option<String>,
    pub export: Option<bool>,
}

impl std::convert::TryFrom<Vec<Assignment>> for Transition {
    type Error = String;

    fn try_from(value: Vec<Assignment>) -> Result<Self, Self::Error> {
        let mut transition = Transition::default();
        for assignment in value.iter() {
            match assignment.field.as_str() {
                "title" => {
                    transition.title = if let Expr::String(s) = &assignment.expr {
                        Some(s.to_string())
                    } else {
                        return Err("title must be a string".to_string());
                    }
                }
                "is_good" => {
                    transition.is_good = Some(assignment.expr.clone());
                }
                "is_bad" => {
                    transition.is_bad = Some(assignment.expr.clone());
                }
                "is_affected" => {
                    transition.is_affected = Some(assignment.expr.clone());
                }
                "notes" => {
                    transition.notes = if let Expr::String(s) = &assignment.expr {
                        Some(s.to_string())
                    } else {
                        return Err("notes must be a string".to_string());
                    }
                }
                "export" => {
                    transition.export = if let Expr::Bool(b) = assignment.expr {
                        Some(b)
                    } else {
                        return Err("export must be a boolean".to_string());
                    }
                }
                n => {
                    log::warn!("Unknown field: {}", n);
                }
            }
        }
        Ok(transition)
    }
}

pub fn read_transition<R: std::io::Read>(reader: &mut R) -> Result<Transition, String> {
    let benfile = read_benfile(reader).map_err(|e| e.to_string())?;
    Transition::try_from(benfile)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_parse_transition() {
        let input = r###"title = "libsoup2.4 -> libsoup3";
is_affected = .build-depends ~ /libsoup2.4-dev|libsoup-gnome2.4-dev|libsoup-3.0-dev/ | .build-depends-arch ~ /libsoup2.4-dev|libsoup-gnome2.4-dev|libsoup-3.0-dev/ | .build-depends ~ /gir1.2-soup-2.4|gir1.2-soup-3.0/ | .depends ~ /gir1.2-soup-2.4/;
is_good = .depends ~ /libsoup-3.0-0|gir1.2-soup-3.0/;
is_bad = .depends ~ /libsoup-2.4-1|libsoup-gnome-2.4-1|gir1.2-soup-2.4/;
notes = "https://bugs.debian.org/cgi-bin/pkgreport.cgi?users=pkg-gnome-maintainers@lists.alioth.debian.org&tag=libsoup2";
export = false;
"###;
        let transition = read_transition(&mut input.as_bytes()).unwrap();
        assert_eq!(transition.title, Some("libsoup2.4 -> libsoup3".to_string()));
        assert_eq!(
            transition.is_affected,
            Some(Expr::Or(vec![
                Box::new(Expr::FieldRegex(
                    "build-depends".to_string(),
                    "libsoup2.4-dev|libsoup-gnome2.4-dev|libsoup-3.0-dev".to_string()
                )),
                Box::new(Expr::FieldRegex(
                    "build-depends-arch".to_string(),
                    "libsoup2.4-dev|libsoup-gnome2.4-dev|libsoup-3.0-dev".to_string()
                )),
                Box::new(Expr::FieldRegex(
                    "build-depends".to_string(),
                    "gir1.2-soup-2.4|gir1.2-soup-3.0".to_string()
                )),
                Box::new(Expr::FieldRegex(
                    "depends".to_string(),
                    "gir1.2-soup-2.4".to_string()
                ))
            ]))
        );
        assert_eq!(
            transition.is_good,
            Some(Expr::FieldRegex(
                "depends".to_string(),
                "libsoup-3.0-0|gir1.2-soup-3.0".to_string()
            ))
        );
        assert_eq!(
            transition.is_bad,
            Some(Expr::FieldRegex(
                "depends".to_string(),
                "libsoup-2.4-1|libsoup-gnome-2.4-1|gir1.2-soup-2.4".to_string()
            ))
        );
        assert_eq!(transition.notes, Some("https://bugs.debian.org/cgi-bin/pkgreport.cgi?users=pkg-gnome-maintainers@lists.alioth.debian.org&tag=libsoup2".to_string()));
        assert_eq!(transition.export, Some(false));
    }
}