summaryrefslogtreecommitdiffstats
path: root/src/file/source
diff options
context:
space:
mode:
authorRyan Leckey <ryan@launchbadge.com>2017-06-14 00:28:43 -0700
committerRyan Leckey <ryan@launchbadge.com>2017-06-14 00:28:43 -0700
commit1716c2fe7571b03215a5ae09c91f508d03335c2a (patch)
treef2b3144044f907c8eb1c594460d6cd74eed92b1f /src/file/source
parent9a2e756075dce24e764c8c89e2d71703a69fd80a (diff)
parent736738a2a798d58b1a73b0da146924a7e92ceba3 (diff)
Merge branch 'feature/with_name' of https://github.com/JordiPolo/config-rs into JordiPolo-feature/with_name
Diffstat (limited to 'src/file/source')
-rw-r--r--src/file/source/file.rs66
-rw-r--r--src/file/source/mod.rs2
-rw-r--r--src/file/source/string.rs4
3 files changed, 48 insertions, 24 deletions
diff --git a/src/file/source/file.rs b/src/file/source/file.rs
index 124b7dd..79f46bf 100644
--- a/src/file/source/file.rs
+++ b/src/file/source/file.rs
@@ -3,9 +3,11 @@ use std::result;
use std::error::Error;
use std::path::{PathBuf, Path};
+use ::file::format::ALL_EXTENSIONS;
use std::io::{self, Read};
use std::fs;
use std::env;
+use std::iter::Iterator;
use source::Source;
use super::{FileFormat, FileSource};
@@ -28,10 +30,9 @@ impl FileSourceFile {
}
}
- fn find_file(&self, format_hint: Option<FileFormat>) -> Result<PathBuf, Box<Error>> {
+ fn find_file(&self, format_hint: Option<FileFormat>) -> Result<(PathBuf, FileFormat), Box<Error>> {
// Build expected configuration file
let mut basename = PathBuf::new();
- let extensions = format_hint.unwrap().extensions();
if let Some(ref path) = self.path {
basename.push(path.clone());
@@ -39,36 +40,59 @@ impl FileSourceFile {
basename.push(self.name.clone());
- // Find configuration file (algorithm similar to .git detection by git)
- let mut dir = env::current_dir()?;
- let mut filename = dir.as_path().join(basename.clone());
+ // First check for an _exact_ match
+ let mut filename = env::current_dir()?.as_path().join(basename.clone());
+ if filename.is_file() {
+ return match format_hint {
+ Some(format) => Ok((filename, format)),
+ None => {
+ for (format, extensions) in ALL_EXTENSIONS.iter() {
+ if extensions.contains(&filename.extension().unwrap_or_default().to_string_lossy().as_ref()) {
+ return Ok((filename, *format));
+ }
+ }
- loop {
- for ext in &extensions {
- filename.set_extension(ext);
+ Err(Box::new(io::Error::new(io::ErrorKind::NotFound,
+ format!("configuration file \"{}\" is not of a registered file format",
+ filename.to_string_lossy()))))
+ }
+ };
+ }
+
+ match format_hint {
+ Some(format) => {
+ for ext in format.extensions() {
+ filename.set_extension(ext);
- if filename.is_file() {
- // File exists and is a file
- return Ok(filename);
+ if filename.is_file() {
+ return Ok((filename, format));
+ }
}
}
- // Not found.. travse up via the dir
- if !dir.pop() {
- // Failed to find the configuration file
- return Err(Box::new(io::Error::new(io::ErrorKind::NotFound,
- format!("configuration file \"{}\" not found",
- basename.to_string_lossy()))
- ));
+ None => {
+ for (format, extensions) in ALL_EXTENSIONS.iter() {
+ for ext in format.extensions() {
+ filename.set_extension(ext);
+
+ if filename.is_file() {
+ return Ok((filename, *format));
+ }
+ }
+ }
}
}
+
+ Err(Box::new(io::Error::new(io::ErrorKind::NotFound,
+ format!("configuration file \"{}\" not found",
+ basename.to_string_lossy()))))
}
}
impl FileSource for FileSourceFile {
- fn resolve(&self, format_hint: Option<FileFormat>) -> Result<(Option<String>, String), Box<Error>> {
+ fn resolve(&self, format_hint: Option<FileFormat>) -> Result<(Option<String>, String, FileFormat), Box<Error>> {
// Find file
- let filename = self.find_file(format_hint)?;
+ let (filename, format) = self.find_file(format_hint)?;
// Attempt to use a relative path for the URI
let base = env::current_dir()?;
@@ -82,7 +106,7 @@ impl FileSource for FileSourceFile {
let mut text = String::new();
file.read_to_string(&mut text)?;
- Ok((Some(uri.to_string_lossy().into_owned()), text))
+ Ok((Some(uri.to_string_lossy().into_owned()), text, format))
}
}
diff --git a/src/file/source/mod.rs b/src/file/source/mod.rs
index 4aeafa5..89f1a3c 100644
--- a/src/file/source/mod.rs
+++ b/src/file/source/mod.rs
@@ -8,5 +8,5 @@ use super::FileFormat;
/// Describes where the file is sourced
pub trait FileSource {
- fn resolve(&self, format_hint: Option<FileFormat>) -> Result<(Option<String>, String), Box<Error>>;
+ fn resolve(&self, format_hint: Option<FileFormat>) -> Result<(Option<String>, String, FileFormat), Box<Error>>;
}
diff --git a/src/file/source/string.rs b/src/file/source/string.rs
index e1d9f64..922e46c 100644
--- a/src/file/source/string.rs
+++ b/src/file/source/string.rs
@@ -15,7 +15,7 @@ impl<'a> From<&'a str> for FileSourceString {
}
impl FileSource for FileSourceString {
- fn resolve(&self, _: Option<FileFormat>) -> Result<(Option<String>, String), Box<Error>> {
- Ok((None, self.0.clone()))
+ fn resolve(&self, format_hint: Option<FileFormat>) -> Result<(Option<String>, String, FileFormat), Box<Error>> {
+ Ok((None, self.0.clone(), format_hint.expect("from_str requires a set file format")))
}
}