diff --git a/src/error.rs b/src/error.rs index 950c09879..de371e923 100644 --- a/src/error.rs +++ b/src/error.rs @@ -16,6 +16,8 @@ pub enum Error { ReferenceInfoError, /// Image probably doesn't exist or has wrong format ImageLoadError, + /// Could not initialize the license detector + LicenseDetectorError, } impl std::fmt::Debug for Error { @@ -29,6 +31,7 @@ impl std::fmt::Debug for Error { Error::BareGitRepo => "Unable to run onefetch on bare git repos", Error::ReferenceInfoError => "Error while retrieving reference information", Error::ImageLoadError => "Could not load the specified image", + Error::LicenseDetectorError => "Could not initialize the license detector", }; write!(f, "{}", content) } diff --git a/src/info.rs b/src/info.rs index 5855c64d3..7e73c45d7 100644 --- a/src/info.rs +++ b/src/info.rs @@ -6,7 +6,7 @@ use std::process::Command; use colored::{Color, ColoredString, Colorize}; use git2::Repository; use image::DynamicImage; -use license; +use license::Detector; use crate::image_backends; use crate::language::Language; @@ -581,6 +581,8 @@ impl Info { } fn get_project_license(dir: &str) -> Result { + let detector = Detector::new()?; + let output = fs::read_dir(dir) .map_err(|_| Error::ReadDirectory)? .filter_map(std::result::Result::ok) @@ -596,7 +598,8 @@ impl Info { }, // TODO: multiple prefixes, like COPYING? ) .filter_map(|entry| { - license::from_text(&fs::read_to_string(entry).unwrap_or_else(|_| "".into())) + let contents = fs::read_to_string(entry).unwrap_or_default(); + detector.analyze(&contents) }) .collect::>() .join(", "); diff --git a/src/license.rs b/src/license.rs index 8ca6b166e..6705d80e5 100644 --- a/src/license.rs +++ b/src/license.rs @@ -1,13 +1,26 @@ use askalono::{Store, TextData}; +use crate::Error; + +type Result = std::result::Result; + static CACHE_DATA: &[u8] = include_bytes!("../resources/license-cache.bin.gz"); -pub fn from_text(text: &str) -> Option { - match Store::from_cache(CACHE_DATA) { - Ok(store) => match store.analyze(&TextData::from(text)) { - Ok(license) => Some(license.name), - Err(_) => None, - }, - Err(_) => None, +pub struct Detector { + store: Store, +} + +impl Detector { + pub fn new() -> Result { + Store::from_cache(CACHE_DATA) + .map(|store| Self { store }) + .map_err(|_| Error::LicenseDetectorError) + } + + pub fn analyze(&self, text: &str) -> Option { + self.store + .analyze(&TextData::from(text)) + .ok() + .map(|license| license.name) } }