use std::str::FromStr;
use aho_corasick::{AcAutomaton, Automaton, Dense};
use {Agpl3, Apache2, Cc01, Gpl3, Lgpl3, Mit, Mpl2, Unknown, Unlicense};
#[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", "Apache License", "Version 2.0", "GNU GENERAL PUBLIC LICENSE", "Version 3", "Mozilla Public License", "This is free and unencumbered software \
released into the public domain.", "GNU LESSER GENERAL PUBLIC LICENSE", "GNU AFFERO GENERAL PUBLIC LICENSE", "CC0 1.0 Universal", ];
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)));
}
}