diff --git a/src/file/mod.rs b/src/file/mod.rs index 342d09bf..64f2ab1e 100644 --- a/src/file/mod.rs +++ b/src/file/mod.rs @@ -55,6 +55,20 @@ impl File { source: source::file::FileSourceFile::new(name.into()), } } + + /// Given the full name of a file, will use it only if with the exact name without + /// any attempt to locate another file. It will analyze the extension if the property + /// format isn't setted but without using file with a different fullname. + pub fn with_exact_name(name: &str) -> Self { + Self::with_name(name).exact(true) + } + + /// If enabeld, and a file with the exact name is not found, + /// will not attempt to locate a file based on the format property. + pub fn exact(mut self, flag: bool) -> Self { + self.source.disable_file_resolve(flag); + self + } } impl<'a> From<&'a Path> for File { diff --git a/src/file/source/file.rs b/src/file/source/file.rs index a413a1fd..435b8728 100644 --- a/src/file/source/file.rs +++ b/src/file/source/file.rs @@ -17,11 +17,18 @@ use source::Source; pub struct FileSourceFile { /// Path of configuration file name: PathBuf, + + /// Raise error if the exact filename is not found + disable_file_resolve: bool, } impl FileSourceFile { pub fn new(name: PathBuf) -> FileSourceFile { - FileSourceFile { name: name } + FileSourceFile { name: name, disable_file_resolve: false } + } + + pub fn disable_file_resolve(&mut self, flag: bool) { + self.disable_file_resolve = flag; } fn find_file( @@ -50,31 +57,33 @@ impl FileSourceFile { io::ErrorKind::NotFound, format!( "configuration file \"{}\" is not of a registered file format", - filename.to_string_lossy() + self.name.to_string_lossy() ), ))) } }; } - match format_hint { - Some(format) => for ext in format.extensions() { - filename.set_extension(ext); - - if filename.is_file() { - return Ok((filename, format)); - } - }, - - None => for (format, extensions) in ALL_EXTENSIONS.iter() { - for ext in format.extensions() { + if !self.disable_file_resolve { + match format_hint { + Some(format) => for ext in format.extensions() { filename.set_extension(ext); if filename.is_file() { - return Ok((filename, *format)); + return Ok((filename, format)); } - } - }, + }, + + 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( diff --git a/tests/Settings.wrongextension b/tests/Settings.wrongextension new file mode 100644 index 00000000..6545b4cc --- /dev/null +++ b/tests/Settings.wrongextension @@ -0,0 +1,8 @@ +debug = false +production = true + +[place] +rating = 4.9 + +[place.creator] +name = "Somebody New" diff --git a/tests/file.rs b/tests/file.rs index 0680c2a1..e1dd61ad 100644 --- a/tests/file.rs +++ b/tests/file.rs @@ -24,6 +24,40 @@ fn test_file_required_not_found() { ); } +#[test] +fn test_file_exact_not_exist() { + let mut c = Config::default(); + let res = c.merge(File::with_exact_name("tests/Settings.wrong")); + + assert!(res.is_err()); + assert_eq!( + res.unwrap_err().to_string(), + "configuration file \"tests/Settings.wrong\" not found".to_string() + ); +} + +#[test] +fn test_file_exact_exist_invalid_extension() { + let mut c = Config::default(); + let res = c.merge(File::with_exact_name("tests/Settings.wrongextension")); + + assert!(res.is_err()); + assert_eq!( + res.unwrap_err().to_string(), + "configuration file \"tests/Settings.wrongextension\" is not of a registered file format".to_string() + ); +} + +#[test] +fn test_file_exact_explicit_format() { + let mut c = Config::default(); + c.merge(File::new("tests/Settings.wrongextension", FileFormat::Toml).exact(true)) + .unwrap(); + + assert_eq!(c.get("debug").ok(), Some(false)); + assert_eq!(c.get("production").ok(), Some(true)); +} + #[test] fn test_file_auto() { let mut c = Config::default();