|
@@ -7,6 +7,8 @@ use std::{
|
|
|
path::{Component, Path, PathBuf},
|
|
|
};
|
|
|
|
|
|
+use walkdir::WalkDir;
|
|
|
+
|
|
|
/// Given a path (absolute or relative) to a resource file, returns the
|
|
|
/// relative path from the bundle resources directory where that resource
|
|
|
/// should be stored.
|
|
@@ -24,6 +26,20 @@ pub fn resource_relpath(path: &Path) -> PathBuf {
|
|
|
dest
|
|
|
}
|
|
|
|
|
|
+fn normalize(path: &Path) -> PathBuf {
|
|
|
+ let mut dest = PathBuf::new();
|
|
|
+ for component in path.components() {
|
|
|
+ match component {
|
|
|
+ Component::Prefix(_) => {}
|
|
|
+ Component::RootDir => dest.push("/"),
|
|
|
+ Component::CurDir => {}
|
|
|
+ Component::ParentDir => dest.push(".."),
|
|
|
+ Component::Normal(string) => dest.push(string),
|
|
|
+ }
|
|
|
+ }
|
|
|
+ dest
|
|
|
+}
|
|
|
+
|
|
|
/// Parses the external binaries to bundle, adding the target triple suffix to each of them.
|
|
|
pub fn external_binaries(external_binaries: &[String], target_triple: &str) -> Vec<String> {
|
|
|
let mut paths = Vec::new();
|
|
@@ -42,6 +58,26 @@ pub fn external_binaries(external_binaries: &[String], target_triple: &str) -> V
|
|
|
paths
|
|
|
}
|
|
|
|
|
|
+/// Information for a resource.
|
|
|
+#[derive(Debug)]
|
|
|
+pub struct Resource {
|
|
|
+ path: PathBuf,
|
|
|
+ target: PathBuf,
|
|
|
+}
|
|
|
+
|
|
|
+impl Resource {
|
|
|
+ /// The path of the resource.
|
|
|
+ pub fn path(&self) -> &Path {
|
|
|
+ &self.path
|
|
|
+ }
|
|
|
+
|
|
|
+ /// The target location of the resource.
|
|
|
+ pub fn target(&self) -> &Path {
|
|
|
+ &self.target
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[derive(Debug)]
|
|
|
enum PatternIter<'a> {
|
|
|
Slice(std::slice::Iter<'a, String>),
|
|
|
Map(std::collections::hash_map::Iter<'a, String, String>),
|
|
@@ -58,12 +94,12 @@ impl<'a> ResourcePaths<'a> {
|
|
|
ResourcePaths {
|
|
|
iter: ResourcePathsIter {
|
|
|
pattern_iter: PatternIter::Slice(patterns.iter()),
|
|
|
- glob_iter: None,
|
|
|
- walk_iter: None,
|
|
|
allow_walk,
|
|
|
+ current_path: None,
|
|
|
current_pattern: None,
|
|
|
- current_pattern_is_valid: false,
|
|
|
current_dest: None,
|
|
|
+ walk_iter: None,
|
|
|
+ glob_iter: None,
|
|
|
},
|
|
|
}
|
|
|
}
|
|
@@ -73,12 +109,12 @@ impl<'a> ResourcePaths<'a> {
|
|
|
ResourcePaths {
|
|
|
iter: ResourcePathsIter {
|
|
|
pattern_iter: PatternIter::Map(patterns.iter()),
|
|
|
- glob_iter: None,
|
|
|
- walk_iter: None,
|
|
|
allow_walk,
|
|
|
+ current_path: None,
|
|
|
current_pattern: None,
|
|
|
- current_pattern_is_valid: false,
|
|
|
current_dest: None,
|
|
|
+ walk_iter: None,
|
|
|
+ glob_iter: None,
|
|
|
},
|
|
|
}
|
|
|
}
|
|
@@ -91,38 +127,143 @@ impl<'a> ResourcePaths<'a> {
|
|
|
}
|
|
|
|
|
|
/// Iterator of a [`ResourcePaths`].
|
|
|
+#[derive(Debug)]
|
|
|
pub struct ResourcePathsIter<'a> {
|
|
|
/// the patterns to iterate.
|
|
|
pattern_iter: PatternIter<'a>,
|
|
|
- /// the glob iterator if the path from the current iteration is a glob pattern.
|
|
|
- glob_iter: Option<glob::Paths>,
|
|
|
- /// the walkdir iterator if the path from the current iteration is a directory.
|
|
|
- walk_iter: Option<walkdir::IntoIter>,
|
|
|
/// whether the resource paths allows directories or not.
|
|
|
allow_walk: bool,
|
|
|
- /// the pattern of the current iteration.
|
|
|
- current_pattern: Option<(String, PathBuf)>,
|
|
|
- /// whether the current pattern is valid or not.
|
|
|
- current_pattern_is_valid: bool,
|
|
|
- /// Current destination path. Only set when the iterator comes from a Map.
|
|
|
+
|
|
|
+ current_path: Option<PathBuf>,
|
|
|
+ current_pattern: Option<String>,
|
|
|
current_dest: Option<PathBuf>,
|
|
|
-}
|
|
|
|
|
|
-/// Information for a resource.
|
|
|
-pub struct Resource {
|
|
|
- path: PathBuf,
|
|
|
- target: PathBuf,
|
|
|
+ walk_iter: Option<walkdir::IntoIter>,
|
|
|
+ glob_iter: Option<glob::Paths>,
|
|
|
}
|
|
|
|
|
|
-impl Resource {
|
|
|
- /// The path of the resource.
|
|
|
- pub fn path(&self) -> &Path {
|
|
|
- &self.path
|
|
|
+impl<'a> ResourcePathsIter<'a> {
|
|
|
+ fn next_glob_iter(&mut self) -> Option<crate::Result<Resource>> {
|
|
|
+ let entry = self.glob_iter.as_mut().unwrap().next()?;
|
|
|
+
|
|
|
+ let entry = match entry {
|
|
|
+ Ok(entry) => entry,
|
|
|
+ Err(err) => return Some(Err(err.into())),
|
|
|
+ };
|
|
|
+
|
|
|
+ self.current_path = Some(normalize(&entry));
|
|
|
+ self.next_current_path()
|
|
|
}
|
|
|
|
|
|
- /// The target location of the resource.
|
|
|
- pub fn target(&self) -> &Path {
|
|
|
- &self.target
|
|
|
+ fn next_walk_iter(&mut self) -> Option<crate::Result<Resource>> {
|
|
|
+ let entry = self.walk_iter.as_mut().unwrap().next()?;
|
|
|
+
|
|
|
+ let entry = match entry {
|
|
|
+ Ok(entry) => entry,
|
|
|
+ Err(err) => return Some(Err(err.into())),
|
|
|
+ };
|
|
|
+
|
|
|
+ self.current_path = Some(normalize(entry.path()));
|
|
|
+ self.next_current_path()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn resource_from_path(&mut self, path: &Path) -> crate::Result<Resource> {
|
|
|
+ if !path.exists() {
|
|
|
+ return Err(crate::Error::ResourcePathNotFound(path.to_path_buf()));
|
|
|
+ }
|
|
|
+
|
|
|
+ Ok(Resource {
|
|
|
+ path: path.to_path_buf(),
|
|
|
+ target: self
|
|
|
+ .current_dest
|
|
|
+ .as_ref()
|
|
|
+ .map(|current_dest| {
|
|
|
+ // if processing a directory, preserve directory structure under current_dest
|
|
|
+ if self.walk_iter.is_some() {
|
|
|
+ let current_pattern = self.current_pattern.as_ref().unwrap();
|
|
|
+ current_dest.join(path.strip_prefix(current_pattern).unwrap_or(path))
|
|
|
+ } else if current_dest.components().count() == 0 {
|
|
|
+ // if current_dest is empty while processing a file pattern or glob
|
|
|
+ // we preserve the file name as it is
|
|
|
+ PathBuf::from(path.file_name().unwrap())
|
|
|
+ } else if self.glob_iter.is_some() {
|
|
|
+ // if processing a glob and current_dest is not empty
|
|
|
+ // we put all globbed paths under current_dest
|
|
|
+ // preserving the file name as it is
|
|
|
+ current_dest.join(path.file_name().unwrap())
|
|
|
+ } else {
|
|
|
+ current_dest.clone()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .unwrap_or_else(|| resource_relpath(path)),
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ fn next_current_path(&mut self) -> Option<crate::Result<Resource>> {
|
|
|
+ // should be safe to unwrap since every call to `self.next_current_path()`
|
|
|
+ // is preceeded with assignemt to `self.current_path`
|
|
|
+ let path = self.current_path.take().unwrap();
|
|
|
+
|
|
|
+ let is_dir = path.is_dir();
|
|
|
+
|
|
|
+ if is_dir {
|
|
|
+ if self.glob_iter.is_some() {
|
|
|
+ return self.next();
|
|
|
+ }
|
|
|
+
|
|
|
+ if !self.allow_walk {
|
|
|
+ return Some(Err(crate::Error::NotAllowedToWalkDir(path.to_path_buf())));
|
|
|
+ }
|
|
|
+
|
|
|
+ if self.walk_iter.is_none() {
|
|
|
+ self.walk_iter = Some(WalkDir::new(&path).into_iter());
|
|
|
+ }
|
|
|
+
|
|
|
+ match self.next_walk_iter() {
|
|
|
+ Some(resource) => Some(resource),
|
|
|
+ None => {
|
|
|
+ self.walk_iter = None;
|
|
|
+ self.next()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ Some(self.resource_from_path(&path))
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fn next_pattern(&mut self) -> Option<crate::Result<Resource>> {
|
|
|
+ self.current_pattern = None;
|
|
|
+ self.current_dest = None;
|
|
|
+ self.current_path = None;
|
|
|
+
|
|
|
+ let pattern = match &mut self.pattern_iter {
|
|
|
+ PatternIter::Slice(iter) => match iter.next() {
|
|
|
+ Some(pattern) => pattern,
|
|
|
+ None => return None,
|
|
|
+ },
|
|
|
+ PatternIter::Map(iter) => match iter.next() {
|
|
|
+ Some((pattern, dest)) => {
|
|
|
+ self.current_pattern = Some(pattern.clone());
|
|
|
+ self.current_dest = Some(resource_relpath(Path::new(dest)));
|
|
|
+ pattern
|
|
|
+ }
|
|
|
+ None => return None,
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ if pattern.contains('*') {
|
|
|
+ self.glob_iter = match glob::glob(pattern) {
|
|
|
+ Ok(glob) => Some(glob),
|
|
|
+ Err(error) => return Some(Err(error.into())),
|
|
|
+ };
|
|
|
+ match self.next_glob_iter() {
|
|
|
+ Some(r) => return Some(r),
|
|
|
+ None => self.glob_iter = None,
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ self.current_path = Some(normalize(Path::new(pattern)));
|
|
|
+ self.next_current_path()
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -134,116 +275,279 @@ impl<'a> Iterator for ResourcePaths<'a> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-fn normalize(path: &Path) -> PathBuf {
|
|
|
- let mut dest = PathBuf::new();
|
|
|
- for component in path.components() {
|
|
|
- match component {
|
|
|
- Component::Prefix(_) => {}
|
|
|
- Component::RootDir => dest.push("/"),
|
|
|
- Component::CurDir => {}
|
|
|
- Component::ParentDir => dest.push(".."),
|
|
|
- Component::Normal(string) => dest.push(string),
|
|
|
+impl<'a> Iterator for ResourcePathsIter<'a> {
|
|
|
+ type Item = crate::Result<Resource>;
|
|
|
+
|
|
|
+ fn next(&mut self) -> Option<crate::Result<Resource>> {
|
|
|
+ if self.current_path.is_some() {
|
|
|
+ return self.next_current_path();
|
|
|
}
|
|
|
+
|
|
|
+ if self.walk_iter.is_some() {
|
|
|
+ match self.next_walk_iter() {
|
|
|
+ Some(r) => return Some(r),
|
|
|
+ None => self.walk_iter = None,
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if self.glob_iter.is_some() {
|
|
|
+ match self.next_glob_iter() {
|
|
|
+ Some(r) => return Some(r),
|
|
|
+ None => self.glob_iter = None,
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ self.next_pattern()
|
|
|
}
|
|
|
- dest
|
|
|
}
|
|
|
|
|
|
-impl<'a> Iterator for ResourcePathsIter<'a> {
|
|
|
- type Item = crate::Result<Resource>;
|
|
|
+#[cfg(test)]
|
|
|
+mod tests {
|
|
|
|
|
|
- fn next(&mut self) -> Option<crate::Result<Resource>> {
|
|
|
- loop {
|
|
|
- if let Some(ref mut walk_entries) = self.walk_iter {
|
|
|
- if let Some(entry) = walk_entries.next() {
|
|
|
- let entry = match entry {
|
|
|
- Ok(entry) => entry,
|
|
|
- Err(error) => return Some(Err(crate::Error::from(error))),
|
|
|
- };
|
|
|
- let path = entry.path();
|
|
|
- if path.is_dir() {
|
|
|
- continue;
|
|
|
- }
|
|
|
- self.current_pattern_is_valid = true;
|
|
|
- return Some(Ok(Resource {
|
|
|
- target: if let (Some(current_dest), Some(current_pattern)) =
|
|
|
- (&self.current_dest, &self.current_pattern)
|
|
|
- {
|
|
|
- if current_pattern.0.contains('*') {
|
|
|
- current_dest.join(path.file_name().unwrap())
|
|
|
- } else {
|
|
|
- current_dest.join(path.strip_prefix(¤t_pattern.1).unwrap())
|
|
|
- }
|
|
|
- } else {
|
|
|
- resource_relpath(path)
|
|
|
- },
|
|
|
- path: path.to_path_buf(),
|
|
|
- }));
|
|
|
- }
|
|
|
+ use super::*;
|
|
|
+ use std::fs;
|
|
|
+ use std::path::Path;
|
|
|
+
|
|
|
+ impl PartialEq for Resource {
|
|
|
+ fn eq(&self, other: &Self) -> bool {
|
|
|
+ self.path == other.path && self.target == other.target
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fn expected_resources(resources: &[(&str, &str)]) -> Vec<Resource> {
|
|
|
+ resources
|
|
|
+ .iter()
|
|
|
+ .map(|(path, target)| Resource {
|
|
|
+ path: Path::new(path).components().collect(),
|
|
|
+ target: Path::new(target).components().collect(),
|
|
|
+ })
|
|
|
+ .collect()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn setup_test_dirs() {
|
|
|
+ let mut random = [0; 1];
|
|
|
+ getrandom::getrandom(&mut random).unwrap();
|
|
|
+
|
|
|
+ let temp = std::env::temp_dir();
|
|
|
+ let temp = temp.join(format!("tauri_resource_paths_iter_test_{}", random[0]));
|
|
|
+
|
|
|
+ let _ = fs::remove_dir_all(&temp);
|
|
|
+ fs::create_dir_all(&temp).unwrap();
|
|
|
+
|
|
|
+ std::env::set_current_dir(&temp).unwrap();
|
|
|
+
|
|
|
+ let paths = [
|
|
|
+ Path::new("src-tauri/tauri.conf.json"),
|
|
|
+ Path::new("src-tauri/some-other-json.json"),
|
|
|
+ Path::new("src-tauri/Cargo.toml"),
|
|
|
+ Path::new("src-tauri/Tauri.toml"),
|
|
|
+ Path::new("src-tauri/build.rs"),
|
|
|
+ Path::new("src/assets/javascript.svg"),
|
|
|
+ Path::new("src/assets/tauri.svg"),
|
|
|
+ Path::new("src/assets/rust.svg"),
|
|
|
+ Path::new("src/assets/lang/en.json"),
|
|
|
+ Path::new("src/assets/lang/ar.json"),
|
|
|
+ Path::new("src/sounds/lang/es.wav"),
|
|
|
+ Path::new("src/sounds/lang/fr.wav"),
|
|
|
+ Path::new("src/textures/ground/earth.tex"),
|
|
|
+ Path::new("src/textures/ground/sand.tex"),
|
|
|
+ Path::new("src/textures/water.tex"),
|
|
|
+ Path::new("src/textures/fire.tex"),
|
|
|
+ Path::new("src/tiles/sky/grey.tile"),
|
|
|
+ Path::new("src/tiles/sky/yellow.tile"),
|
|
|
+ Path::new("src/tiles/grass.tile"),
|
|
|
+ Path::new("src/tiles/stones.tile"),
|
|
|
+ Path::new("src/index.html"),
|
|
|
+ Path::new("src/style.css"),
|
|
|
+ Path::new("src/script.js"),
|
|
|
+ ];
|
|
|
+
|
|
|
+ for path in paths {
|
|
|
+ fs::create_dir_all(path.parent().unwrap()).unwrap();
|
|
|
+ fs::write(path, "").unwrap();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ #[serial_test::serial]
|
|
|
+ fn resource_paths_iter_slice_allow_walk() {
|
|
|
+ setup_test_dirs();
|
|
|
+
|
|
|
+ let dir = std::env::current_dir().unwrap().join("src-tauri");
|
|
|
+ let _ = std::env::set_current_dir(dir);
|
|
|
+
|
|
|
+ let resources = ResourcePaths::new(
|
|
|
+ &[
|
|
|
+ "../src/script.js".into(),
|
|
|
+ "../src/assets".into(),
|
|
|
+ "../src/index.html".into(),
|
|
|
+ "../src/sounds".into(),
|
|
|
+ "*.toml".into(),
|
|
|
+ "*.conf.json".into(),
|
|
|
+ ],
|
|
|
+ true,
|
|
|
+ )
|
|
|
+ .iter()
|
|
|
+ .flatten()
|
|
|
+ .collect::<Vec<_>>();
|
|
|
+
|
|
|
+ let expected = expected_resources(&[
|
|
|
+ ("../src/script.js", "_up_/src/script.js"),
|
|
|
+ (
|
|
|
+ "../src/assets/javascript.svg",
|
|
|
+ "_up_/src/assets/javascript.svg",
|
|
|
+ ),
|
|
|
+ ("../src/assets/tauri.svg", "_up_/src/assets/tauri.svg"),
|
|
|
+ ("../src/assets/rust.svg", "_up_/src/assets/rust.svg"),
|
|
|
+ ("../src/assets/lang/en.json", "_up_/src/assets/lang/en.json"),
|
|
|
+ ("../src/assets/lang/ar.json", "_up_/src/assets/lang/ar.json"),
|
|
|
+ ("../src/index.html", "_up_/src/index.html"),
|
|
|
+ ("../src/sounds/lang/es.wav", "_up_/src/sounds/lang/es.wav"),
|
|
|
+ ("../src/sounds/lang/fr.wav", "_up_/src/sounds/lang/fr.wav"),
|
|
|
+ ("Cargo.toml", "Cargo.toml"),
|
|
|
+ ("Tauri.toml", "Tauri.toml"),
|
|
|
+ ("tauri.conf.json", "tauri.conf.json"),
|
|
|
+ ]);
|
|
|
+
|
|
|
+ assert_eq!(resources.len(), expected.len());
|
|
|
+ for resource in expected {
|
|
|
+ if !resources.contains(&resource) {
|
|
|
+ panic!("{resource:?} was expected but not found in {resources:?}");
|
|
|
}
|
|
|
- self.walk_iter = None;
|
|
|
- if let Some(ref mut glob_paths) = self.glob_iter {
|
|
|
- if let Some(glob_result) = glob_paths.next() {
|
|
|
- let path = match glob_result {
|
|
|
- Ok(path) => path,
|
|
|
- Err(error) => return Some(Err(error.into())),
|
|
|
- };
|
|
|
- if path.is_dir() {
|
|
|
- if self.allow_walk {
|
|
|
- let walk = walkdir::WalkDir::new(path);
|
|
|
- self.walk_iter = Some(walk.into_iter());
|
|
|
- continue;
|
|
|
- } else {
|
|
|
- return Some(Err(crate::Error::NotAllowedToWalkDir(path)));
|
|
|
- }
|
|
|
- }
|
|
|
- self.current_pattern_is_valid = true;
|
|
|
- return Some(Ok(Resource {
|
|
|
- target: if let Some(current_dest) = &self.current_dest {
|
|
|
- current_dest.join(path.file_name().unwrap())
|
|
|
- } else {
|
|
|
- resource_relpath(&path)
|
|
|
- },
|
|
|
- path,
|
|
|
- }));
|
|
|
- } else if let Some(current_path) = &self.current_pattern {
|
|
|
- if !self.current_pattern_is_valid {
|
|
|
- self.glob_iter = None;
|
|
|
- return Some(Err(crate::Error::GlobPathNotFound(current_path.0.clone())));
|
|
|
- }
|
|
|
- }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ #[serial_test::serial]
|
|
|
+ fn resource_paths_iter_slice_no_walk() {
|
|
|
+ setup_test_dirs();
|
|
|
+
|
|
|
+ let dir = std::env::current_dir().unwrap().join("src-tauri");
|
|
|
+ let _ = std::env::set_current_dir(dir);
|
|
|
+
|
|
|
+ let resources = ResourcePaths::new(
|
|
|
+ &[
|
|
|
+ "../src/script.js".into(),
|
|
|
+ "../src/assets".into(),
|
|
|
+ "../src/index.html".into(),
|
|
|
+ "../src/sounds".into(),
|
|
|
+ "*.toml".into(),
|
|
|
+ "*.conf.json".into(),
|
|
|
+ ],
|
|
|
+ false,
|
|
|
+ )
|
|
|
+ .iter()
|
|
|
+ .flatten()
|
|
|
+ .collect::<Vec<_>>();
|
|
|
+
|
|
|
+ let expected = expected_resources(&[
|
|
|
+ ("../src/script.js", "_up_/src/script.js"),
|
|
|
+ ("../src/index.html", "_up_/src/index.html"),
|
|
|
+ ("Cargo.toml", "Cargo.toml"),
|
|
|
+ ("Tauri.toml", "Tauri.toml"),
|
|
|
+ ("tauri.conf.json", "tauri.conf.json"),
|
|
|
+ ]);
|
|
|
+
|
|
|
+ assert_eq!(resources.len(), expected.len());
|
|
|
+ for resource in expected {
|
|
|
+ if !resources.contains(&resource) {
|
|
|
+ panic!("{resource:?} was expected but not found in {resources:?}");
|
|
|
}
|
|
|
- self.glob_iter = None;
|
|
|
- self.current_dest = None;
|
|
|
- match &mut self.pattern_iter {
|
|
|
- PatternIter::Slice(iter) => {
|
|
|
- if let Some(pattern) = iter.next() {
|
|
|
- self.current_pattern = Some((pattern.to_string(), normalize(Path::new(pattern))));
|
|
|
- self.current_pattern_is_valid = false;
|
|
|
- let glob = match glob::glob(pattern) {
|
|
|
- Ok(glob) => glob,
|
|
|
- Err(error) => return Some(Err(error.into())),
|
|
|
- };
|
|
|
- self.glob_iter = Some(glob);
|
|
|
- continue;
|
|
|
- }
|
|
|
- }
|
|
|
- PatternIter::Map(iter) => {
|
|
|
- if let Some((pattern, dest)) = iter.next() {
|
|
|
- self.current_pattern = Some((pattern.to_string(), normalize(Path::new(pattern))));
|
|
|
- self.current_pattern_is_valid = false;
|
|
|
- let glob = match glob::glob(pattern) {
|
|
|
- Ok(glob) => glob,
|
|
|
- Err(error) => return Some(Err(error.into())),
|
|
|
- };
|
|
|
- self
|
|
|
- .current_dest
|
|
|
- .replace(resource_relpath(&PathBuf::from(dest)));
|
|
|
- self.glob_iter = Some(glob);
|
|
|
- continue;
|
|
|
- }
|
|
|
- }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ #[serial_test::serial]
|
|
|
+ fn resource_paths_iter_map_allow_walk() {
|
|
|
+ setup_test_dirs();
|
|
|
+
|
|
|
+ let dir = std::env::current_dir().unwrap().join("src-tauri");
|
|
|
+ let _ = std::env::set_current_dir(dir);
|
|
|
+
|
|
|
+ let resources = ResourcePaths::from_map(
|
|
|
+ &std::collections::HashMap::from_iter([
|
|
|
+ ("../src/script.js".into(), "main.js".into()),
|
|
|
+ ("../src/assets".into(), "".into()),
|
|
|
+ ("../src/index.html".into(), "frontend/index.html".into()),
|
|
|
+ ("../src/sounds".into(), "voices".into()),
|
|
|
+ ("../src/textures/*".into(), "textures".into()),
|
|
|
+ ("../src/tiles/**/*".into(), "tiles".into()),
|
|
|
+ ("*.toml".into(), "".into()),
|
|
|
+ ("*.conf.json".into(), "json".into()),
|
|
|
+ ("../non-existent-file".into(), "asd".into()), // invalid case
|
|
|
+ ("../non/*".into(), "asd".into()), // invalid case
|
|
|
+ ]),
|
|
|
+ true,
|
|
|
+ )
|
|
|
+ .iter()
|
|
|
+ .flatten()
|
|
|
+ .collect::<Vec<_>>();
|
|
|
+
|
|
|
+ let expected = expected_resources(&[
|
|
|
+ ("../src/script.js", "main.js"),
|
|
|
+ ("../src/assets/javascript.svg", "javascript.svg"),
|
|
|
+ ("../src/assets/tauri.svg", "tauri.svg"),
|
|
|
+ ("../src/assets/rust.svg", "rust.svg"),
|
|
|
+ ("../src/assets/lang/en.json", "lang/en.json"),
|
|
|
+ ("../src/assets/lang/ar.json", "lang/ar.json"),
|
|
|
+ ("../src/index.html", "frontend/index.html"),
|
|
|
+ ("../src/sounds/lang/es.wav", "voices/lang/es.wav"),
|
|
|
+ ("../src/sounds/lang/fr.wav", "voices/lang/fr.wav"),
|
|
|
+ ("../src/textures/water.tex", "textures/water.tex"),
|
|
|
+ ("../src/textures/fire.tex", "textures/fire.tex"),
|
|
|
+ ("../src/tiles/grass.tile", "tiles/grass.tile"),
|
|
|
+ ("../src/tiles/stones.tile", "tiles/stones.tile"),
|
|
|
+ ("../src/tiles/sky/grey.tile", "tiles/grey.tile"),
|
|
|
+ ("../src/tiles/sky/yellow.tile", "tiles/yellow.tile"),
|
|
|
+ ("Cargo.toml", "Cargo.toml"),
|
|
|
+ ("Tauri.toml", "Tauri.toml"),
|
|
|
+ ("tauri.conf.json", "json/tauri.conf.json"),
|
|
|
+ ]);
|
|
|
+
|
|
|
+ assert_eq!(resources.len(), expected.len());
|
|
|
+ for resource in expected {
|
|
|
+ if !resources.contains(&resource) {
|
|
|
+ panic!("{resource:?} was expected but not found in {resources:?}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ #[serial_test::serial]
|
|
|
+ fn resource_paths_iter_map_no_walk() {
|
|
|
+ setup_test_dirs();
|
|
|
+
|
|
|
+ let dir = std::env::current_dir().unwrap().join("src-tauri");
|
|
|
+ let _ = std::env::set_current_dir(dir);
|
|
|
+
|
|
|
+ let resources = ResourcePaths::from_map(
|
|
|
+ &std::collections::HashMap::from_iter([
|
|
|
+ ("../src/script.js".into(), "main.js".into()),
|
|
|
+ ("../src/assets".into(), "".into()),
|
|
|
+ ("../src/index.html".into(), "frontend/index.html".into()),
|
|
|
+ ("../src/sounds".into(), "voices".into()),
|
|
|
+ ("*.toml".into(), "".into()),
|
|
|
+ ("*.conf.json".into(), "json".into()),
|
|
|
+ ]),
|
|
|
+ false,
|
|
|
+ )
|
|
|
+ .iter()
|
|
|
+ .flatten()
|
|
|
+ .collect::<Vec<_>>();
|
|
|
+
|
|
|
+ let expected = expected_resources(&[
|
|
|
+ ("../src/script.js", "main.js"),
|
|
|
+ ("../src/index.html", "frontend/index.html"),
|
|
|
+ ("Cargo.toml", "Cargo.toml"),
|
|
|
+ ("Tauri.toml", "Tauri.toml"),
|
|
|
+ ("tauri.conf.json", "json/tauri.conf.json"),
|
|
|
+ ]);
|
|
|
+
|
|
|
+ assert_eq!(resources.len(), expected.len());
|
|
|
+ for resource in expected {
|
|
|
+ if !resources.contains(&resource) {
|
|
|
+ panic!("{resource:?} was expected but not found in {resources:?}");
|
|
|
}
|
|
|
- return None;
|
|
|
}
|
|
|
}
|
|
|
}
|