summaryrefslogtreecommitdiffstats
path: root/src/file/source/file.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/file/source/file.rs')
-rw-r--r--src/file/source/file.rs66
1 files changed, 45 insertions, 21 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))
}
}