[go: up one dir, main page]

license 0.3.0

A license library.
Documentation
use std::str::FromStr;

use aho_corasick::{AcAutomaton, Automaton, Dense};

use {Agpl3, Apache2, Cc01, Gpl3, Lgpl3, Mit, Mpl2, Unknown, Unlicense};

/// Enum containing all supported licenses.
///
/// # Examples
/// ```
/// use std::str::FromStr;
/// use license::{Apache2, Gpl3, Kind};
///
/// // From text:
/// let apache2 = Kind::from_str(include_str!("../files/APACHE-2"));
/// assert_eq!(apache2, Ok(Kind::Apache2(Apache2)));
///
/// // From identity:
/// let gpl3 = Kind::from_str("GPL-3.0");
/// assert_eq!(gpl3, Ok(Kind::Gpl3(Gpl3)));
/// ```
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub enum Kind {
    Agpl3(Agpl3),
    Apache2(Apache2),
    Cc01(Cc01),
    Gpl3(Gpl3),
    Lgpl3(Lgpl3),
    Mit(Mit),
    Mpl2(Mpl2),
    Unlicense(Unlicense),
}

impl FromStr for Kind {
    type Err = Unknown;

    #[inline]
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "AGPL-3.0" => Ok(Kind::Agpl3(Agpl3)),
            "Apache-2.0" => Ok(Kind::Apache2(Apache2)),
            "CC0-1.0" => Ok(Kind::Cc01(Cc01)),
            "GPL-3.0" => Ok(Kind::Gpl3(Gpl3)),
            "LGPL-3.0" => Ok(Kind::Lgpl3(Lgpl3)),
            "MIT" => Ok(Kind::Mit(Mit::default())),
            "MPL-2.0" => Ok(Kind::Mpl2(Mpl2)),
            "Unlicense" => Ok(Kind::Unlicense(Unlicense)),
            s => {
                lazy_static! {
                    static ref AHO: AcAutomaton<&'static &'static str, Dense> = {
                        const PATS: &[&str] = &[
                            "MIT License",                                  // 0
                            "Apache License",                               // 1
                            "Version 2.0",                                  // 2
                            "GNU GENERAL PUBLIC LICENSE",                   // 3
                            "Version 3",                                    // 4
                            "Mozilla Public License",                       // 5
                            "This is free and unencumbered software \
                            released into the public domain.",              // 6
                            "GNU LESSER GENERAL PUBLIC LICENSE",            // 7
                            "GNU AFFERO GENERAL PUBLIC LICENSE",            // 8
                            "CC0 1.0 Universal",                            // 9
                        ];
                        AcAutomaton::new(PATS)
                    };
                }
                let mut it = AHO.find(s);
                match it.next() {
                    Some(m) => match m.pati {
                        0 => Ok(Kind::Mit(Mit(s.to_string()))),
                        1 => match it.next() {
                            Some(m) if m.pati == 2 => Ok(Kind::Apache2(Apache2)),
                            _ => Err(Unknown),
                        },
                        3 => match it.next() {
                            Some(m) if m.pati == 4 => Ok(Kind::Gpl3(Gpl3)),
                            _ => Err(Unknown),
                        },
                        5 => match it.next() {
                            Some(m) if m.pati == 2 => Ok(Kind::Mpl2(Mpl2)),
                            _ => Err(Unknown),
                        },
                        6 => Ok(Kind::Unlicense(Unlicense)),
                        7 => match it.next() {
                            Some(m) if m.pati == 4 => Ok(Kind::Lgpl3(Lgpl3)),
                            _ => Err(Unknown),
                        },
                        8 => match it.next() {
                            Some(m) if m.pati == 4 => Ok(Kind::Agpl3(Agpl3)),
                            _ => Err(Unknown),
                        },
                        9 => Ok(Kind::Cc01(Cc01)),
                        _ => Err(Unknown),
                    },
                    None => Err(Unknown),
                }
            }
        }
    }
}

impl From<Agpl3> for Kind {
    #[inline]
    fn from(agpl3: Agpl3) -> Self {
        Kind::Agpl3(agpl3)
    }
}

impl From<Apache2> for Kind {
    #[inline]
    fn from(apache2: Apache2) -> Self {
        Kind::Apache2(apache2)
    }
}

impl From<Cc01> for Kind {
    #[inline]
    fn from(cc01: Cc01) -> Self {
        Kind::Cc01(cc01)
    }
}

impl From<Gpl3> for Kind {
    #[inline]
    fn from(gpl3: Gpl3) -> Self {
        Kind::Gpl3(gpl3)
    }
}

impl From<Lgpl3> for Kind {
    #[inline]
    fn from(lgpl3: Lgpl3) -> Self {
        Kind::Lgpl3(lgpl3)
    }
}

impl From<Mit> for Kind {
    #[inline]
    fn from(mit: Mit) -> Self {
        Kind::Mit(mit)
    }
}

impl From<Mpl2> for Kind {
    #[inline]
    fn from(mpl2: Mpl2) -> Self {
        Kind::Mpl2(mpl2)
    }
}

impl From<Unlicense> for Kind {
    #[inline]
    fn from(unlicense: Unlicense) -> Self {
        Kind::Unlicense(unlicense)
    }
}

#[cfg(test)]
mod test {
    use std::str::FromStr;
    use ::*;

    #[test]
    fn from_id() {
        let agpl3 = Kind::from_str("AGPL-3.0");
        assert_eq!(agpl3, Ok(Kind::Agpl3(Agpl3)));

        let apache2 = Kind::from_str("Apache-2.0");
        assert_eq!(apache2, Ok(Kind::Apache2(Apache2)));

        let cc01 = Kind::from_str("CC0-1.0");
        assert_eq!(cc01, Ok(Kind::Cc01(Cc01)));

        let gpl3 = Kind::from_str("GPL-3.0");
        assert_eq!(gpl3, Ok(Kind::Gpl3(Gpl3)));

        let lgpl3 = Kind::from_str("LGPL-3.0");
        assert_eq!(lgpl3, Ok(Kind::Lgpl3(Lgpl3)));

        let mit = Kind::from_str("MIT");
        assert_eq!(mit, Ok(Kind::Mit(Mit::default())));

        let mpl2 = Kind::from_str("MPL-2.0");
        assert_eq!(mpl2, Ok(Kind::Mpl2(Mpl2)));

        let unlicense = Kind::from_str("Unlicense");
        assert_eq!(unlicense, Ok(Kind::Unlicense(Unlicense)));
    }

    #[test]
    fn from_text() {
        let agpl3 = Kind::from_str(include_str!("../files/AGPL-3"));
        assert_eq!(agpl3, Ok(Kind::Agpl3(Agpl3)));

        let apache2 = Kind::from_str(include_str!("../files/APACHE-2"));
        assert_eq!(apache2, Ok(Kind::Apache2(Apache2)));

        let cc01 = Kind::from_str(include_str!("../files/CC0-1"));
        assert_eq!(cc01, Ok(Kind::Cc01(Cc01)));

        let gpl3 = Kind::from_str(include_str!("../files/GPL-3"));
        assert_eq!(gpl3, Ok(Kind::Gpl3(Gpl3)));

        let lgpl3 = Kind::from_str(include_str!("../files/LGPL-3"));
        assert_eq!(lgpl3, Ok(Kind::Lgpl3(Lgpl3)));

        let mit =
            Kind::from_str(&format!(include_str!("../files/MIT"), 2017, "Mr. Foo Bar"));
        assert_eq!(mit, Ok(Kind::Mit(Mit::new(2017, "Mr. Foo Bar"))));

        let mpl2 = Kind::from_str(include_str!("../files/MPL-2"));
        assert_eq!(mpl2, Ok(Kind::Mpl2(Mpl2)));

        let unlicense = Kind::from_str(include_str!("../files/UNLICENSE"));
        assert_eq!(unlicense, Ok(Kind::Unlicense(Unlicense)));
    }
}