Repository: shssoichiro/oxipng (language: rust)

Issue:
Windows: Cannot specify infile in double quotes
When trying to specify files for optimization in double quotes (e.g. when path to file(s) contain spaces),
`oxipng -o max "folder with spaces\*.png"`
 then oxipng throws error "Failed to open file for reading".
Double quotes work though when used in option
`--dir "folder name with spaces\and subfolder"`
Is there a chance for this to be fixed?
Thanks in advance


Discussion / hints:
Same here, I can't figure out how make my bat file to work:
```
@echo off
pushd %~dp0
oxipng -s "%~1\*.png"
echo.
pause
```
Update. Do it :call_me_hand:
This [thread](https://stackoverflow.com/questions/180741/how-to-do-something-to-each-file-in-a-directory-with-a-batch-script) was helpful.
```
@echo off
pushd %~dp0
for /f tokens^=* %%i in ('where "%~1":*.png') do (
	oxipng -s --dir "%~1" "%%~dpnxi"
	echo.
	)
pause
```
> Update. Do it :call_me_hand:
> This [thread](https://stackoverflow.com/questions/180741/how-to-do-something-to-each-file-in-a-directory-with-a-batch-script) was helpful.
> ```
> @echo off
> pushd %~dp0
> for /f tokens^=* %%i in ('where "%~1":*.png') do (
> 	oxipng -s --dir "%~1" "%%~dpnxi"
> 	echo.
> 	)
> pause
> ```

@Vasilich Does this solve for you?  If so, limitation of Windows batch file & not OxiPNG, & so issue should be closed.  🙇🏾‍♂️
> > Update. Do it call_me_hand
> > This [thread](https://stackoverflow.com/questions/180741/how-to-do-something-to-each-file-in-a-directory-with-a-batch-script) was helpful.
> > ```
> > @echo off
> > pushd %~dp0
> > for /f tokens^=* %%i in ('where "%~1":*.png') do (
> > 	oxipng -s --dir "%~1" "%%~dpnxi"
> > 	echo.
> > 	)
> > pause
> > ```
> 
> @Vasilich Does this solve for you? If so, limitation of Windows batch file & not OxiPNG, & so issue should be closed. 🙇🏾‍♂️

The idea of the last script is that it collects all the files in the directory and runs a new instance of OxiPNG for each one, substituting the full path to the file.

I hope that OxiPNG will have a built-in batch processing of files from directory, i.e. when calling `oxipng -s "%~1\*.png"` the program will parse the directory itself and perform optimization for each file without restarting.

I found a [similar problem](https://github.com/shssoichiro/oxipng/issues/90) among those solved. Maybe the current problem is a special case of this solved problem.
> @Vasilich Does this solve for you? If so, limitation of Windows batch file & not OxiPNG, & so issue should be closed. 🙇🏾‍♂️

No, it doesn't solve this problem, it just workarounds it.
I made similar workaround 2 years ago, but wanted it to be fixed for OxiPng. See my 1st post- it is not Windows problem - other argument works perfectly with quotes on Windows.
BTW, how should i specify file mask with path containing spaces in Linux?



Fix patch:
diff --git a/Cargo.lock b/Cargo.lock
index 793b7beb..4bb9bd27 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -457,6 +457,7 @@ dependencies = [
  "crossbeam-channel",
  "env_logger",
  "filetime",
+ "glob",
  "image",
  "indexmap",
  "libdeflater",
@@ -465,7 +466,6 @@ dependencies = [
  "rgb",
  "rustc-hash",
  "rustc_version",
- "wild",
  "zopfli",
 ]
 
@@ -608,15 +608,6 @@ version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
 
-[[package]]
-name = "wild"
-version = "2.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05b116685a6be0c52f5a103334cbff26db643826c7b3735fc0a3ba9871310a74"
-dependencies = [
- "glob",
-]
-
 [[package]]
 name = "winapi"
 version = "0.3.9"
diff --git a/Cargo.toml b/Cargo.toml
index 7e06f4c4..acca5133 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -57,9 +57,9 @@ version = "1.7.0"
 optional = true
 version = "4.3.8"
 
-[dependencies.wild]
+[target.'cfg(windows)'.dependencies.glob]
 optional = true
-version = "2.1.0"
+version = "0.3.1"
 
 [dependencies.image]
 optional = true
@@ -71,7 +71,7 @@ version = "0.24.6"
 rustc_version = "0.4.0"
 
 [features]
-binary = ["clap", "wild", "env_logger"]
+binary = ["clap", "glob", "env_logger"]
 default = ["binary", "filetime", "parallel", "zopfli"]
 parallel = ["rayon", "indexmap/rayon", "crossbeam-channel"]
 freestanding = ["libdeflater/freestanding"]
diff --git a/src/main.rs b/src/main.rs
index d0d14f0e..d2343edf 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -296,7 +296,7 @@ Heuristic filter selection strategies:
     8  =>  BigEnt    Highest Shannon entropy of bigrams
     9  =>  Brute     Smallest compressed size (slow)",
         )
-        .get_matches_from(wild::args());
+        .get_matches_from(std::env::args());
 
     let (out_file, out_dir, opts) = match parse_opts_into_struct(&matches) {
         Ok(x) => x,
@@ -307,6 +307,14 @@ Heuristic filter selection strategies:
     };
 
     let files = collect_files(
+        #[cfg(windows)]
+        matches
+            .get_many::<PathBuf>("files")
+            .unwrap()
+            .cloned()
+            .flat_map(apply_glob_pattern)
+            .collect(),
+        #[cfg(not(windows))]
         matches
             .get_many::<PathBuf>("files")
             .unwrap()
@@ -384,6 +392,19 @@ fn collect_files(
     in_out_pairs
 }
 
+#[cfg(windows)]
+fn apply_glob_pattern(path: PathBuf) -> Vec<PathBuf> {
+    let matches = path
+        .to_str()
+        .and_then(|pattern| glob::glob(pattern).ok())
+        .map(|paths| paths.flatten().collect::<Vec<_>>());
+
+    match matches {
+        Some(paths) if !paths.is_empty() => paths,
+        _ => vec![path],
+    }
+}
+
 fn parse_opts_into_struct(
     matches: &ArgMatches,
 ) -> Result<(OutFile, Option<PathBuf>, Options), String> {


Test patch: