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
pub mod analyze;
pub mod errors;
pub mod output;
pub mod wpscan;

pub use analyze::{default_analysis, AnalysisSummary, Summary, WpScanAnalysis};
pub use output::{OutputConfig, OutputDetail, OutputFormat};
pub use wpscan::WpScan;

use errors::*;

use failure::Fail;
use serde::de::{self, Deserialize, Deserializer};
use std::fmt::Display;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::str::FromStr;

pub trait FromFile {
    fn from_file<P: AsRef<Path>, E>(path: P) -> ::std::result::Result<Self, Error>
    where
        Self: Sized + FromStr<Err = E>,
        E: Fail,
    {
        let contents = Self::string_from_file(path.as_ref()).map_err(|e| {
            e.context(ErrorKind::InvalidFile(
                path.as_ref().to_string_lossy().into_owned(),
            ))
        })?;

        Self::from_str(&contents).map_err(|_| Error::from(ErrorKind::InvalidFormat))
    }

    fn string_from_file<P: AsRef<Path>>(
        path: P,
    ) -> ::std::result::Result<String, ::std::io::Error> {
        let path: &Path = path.as_ref();

        let mut file = File::open(path)?;
        let mut contents = String::new();
        let _ = file.read_to_string(&mut contents)?;

        Ok(contents)
    }
}

pub trait SanityCheck {
    type Error;
    fn is_sane(&self) -> ::std::result::Result<(), Self::Error>;
}

fn from_str<'de, T, D>(deserializer: D) -> ::std::result::Result<T, D::Error>
where
    T: FromStr,
    T::Err: Display,
    D: Deserializer<'de>,
{
    let s = String::deserialize(deserializer)?;
    T::from_str(&s).map_err(de::Error::custom)
}