summaryrefslogtreecommitdiff
path: root/src/context.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/context.rs')
-rw-r--r--src/context.rs105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/context.rs b/src/context.rs
new file mode 100644
index 0000000..6bc4c05
--- /dev/null
+++ b/src/context.rs
@@ -0,0 +1,105 @@
+use structopt::StructOpt;
+use serde::Deserialize;
+use std::collections::HashMap;
+use std::fs;
+use std::io;
+use std::path::PathBuf;
+
+#[derive(Debug, StructOpt)]
+#[structopt(name = "gallery")]
+pub struct Options {
+ #[structopt(long, help = "Just a thing")]
+ pub check: bool,
+ #[structopt(short, long, help = "Config file location")]
+ pub config: Option<PathBuf>,
+ #[structopt(help = "Picture location")]
+ pub load: PathBuf,
+}
+
+#[derive(Debug)]
+pub enum ConfigError {
+ Reading(io::Error),
+ Parsing(serde_yaml::Error),
+ CompilePattern(glob::PatternError),
+}
+
+#[derive(Deserialize, Debug)]
+pub struct Config {
+ pub imageglob: String,
+ pub info: HashMap<String, String>,
+
+ #[serde(skip)]
+ pub imageglob_compiled: glob::Pattern,
+}
+
+#[derive(Debug)]
+pub struct Context {
+ pub options: Options,
+ pub config: Config,
+}
+
+impl Context {
+ pub fn new_with_args() -> Result<Context, ConfigError> {
+ let opts = Options::from_args();
+ let config = Config::load_with_options(&opts)?;
+
+ Ok(Context {
+ options: opts,
+ config: config,
+ })
+ }
+
+ pub fn get_image_files(&self) -> Result<Vec<PathBuf>, io::Error> {
+ let files = fs::read_dir(&self.options.load)?
+ // Remove errored entries (SILENTLY)
+ .filter(|entry| entry.is_ok())
+ .map(|entry| entry.unwrap().path())
+ // Filter out directories and files that do not match pattern
+ .filter(|path| path.file_name()
+ .map_or(false, |file| self.config.imageglob_compiled.matches(file.to_str().unwrap()))
+ )
+ .collect();
+
+ Ok(files)
+ }
+}
+
+impl Config {
+ fn load_from_file(path: &PathBuf) -> Result<Config, ConfigError> {
+ let content = fs::read_to_string(path)?;
+ let mut config: Config = serde_yaml::from_str(&content)?;
+
+ config.imageglob_compiled = glob::Pattern::new(&config.imageglob)?;
+
+ Ok(config)
+ }
+
+ pub fn load_with_options(opts: &Options) -> Result<Config, ConfigError> {
+ let config_path = match &opts.config {
+ Some(path) => path.to_path_buf(),
+ None => opts.load.join("imginfo.yml"),
+ };
+
+ Config::load_from_file(&config_path)
+ }
+
+
+}
+
+impl From<io::Error> for ConfigError {
+ fn from(error: io::Error) -> Self {
+ ConfigError::Reading(error)
+ }
+}
+
+impl From<serde_yaml::Error> for ConfigError {
+ fn from(error: serde_yaml::Error) -> Self {
+ ConfigError::Parsing(error)
+ }
+}
+
+impl From<glob::PatternError> for ConfigError {
+ fn from(error: glob::PatternError) -> Self {
+ ConfigError::CompilePattern(error)
+ }
+}