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
#![deny(missing_docs)]

//! An interface for linting tools
//!
//! This is experimental work in progress, expect breaking changes!

/// The outcome of a check.
pub enum Outcome<'a> {
    /// The check passed.
    Passed(&'a str),
    /// The check failed.
    Failed(&'a str),
    /// The check was ignored.
    Ignored,
}

impl<'a> Outcome<'a> {
    /// Check whether the outcome is failed.
    pub fn is_failed(&self) -> bool {
        use Outcome::*;
        match *self {
            Passed(_) | Ignored => false,
            Failed(_) => true,
        }
    }
}

/// A summary giving short information about a check.
#[derive(Debug, PartialEq)]
pub enum Summary {
    /// The check was ok, no failures were found.
    Ok,
    /// At least one failure was found.
    NotOk,
}

impl Summary {
    /// Check whether the summary is ok.
    pub fn is_ok(&self) -> bool {
        *self == Summary::Ok
    }
}

/// A trait for checks that can be implemented.
pub trait Check {
    /// Runs the check.
    ///
    /// This is the only method that is required by implementors.
    ///
    /// The implementation should call f for each check that was run,
    /// so that the caller gets notified about the outcome.
    fn check(&self, f: &mut FnMut(&Outcome));

    /// Run the check and return a summary.
    ///
    /// This method runs the check and records the calls to the f
    /// parameter, collecting a summary over all of them.
    fn check_ok(&self, f: &mut FnMut(&Outcome)) -> Summary {
        let mut ok = Summary::Ok;
        self.check(&mut |o| {
            if o.is_failed() {
                ok = Summary::NotOk;
            }
            f(o)
        });
        ok
    }
}