Julio Biason
1 year ago
4 changed files with 325 additions and 0 deletions
@ -0,0 +1,211 @@
|
||||
# This file is automatically @generated by Cargo. |
||||
# It is not intended for manual editing. |
||||
version = 3 |
||||
|
||||
[[package]] |
||||
name = "addr2line" |
||||
version = "0.21.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" |
||||
dependencies = [ |
||||
"gimli", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "adler" |
||||
version = "1.0.2" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" |
||||
|
||||
[[package]] |
||||
name = "aho-corasick" |
||||
version = "1.0.5" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" |
||||
dependencies = [ |
||||
"memchr", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "async-recursion" |
||||
version = "1.0.5" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" |
||||
dependencies = [ |
||||
"proc-macro2", |
||||
"quote", |
||||
"syn", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "backtrace" |
||||
version = "0.3.69" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" |
||||
dependencies = [ |
||||
"addr2line", |
||||
"cc", |
||||
"cfg-if", |
||||
"libc", |
||||
"miniz_oxide", |
||||
"object", |
||||
"rustc-demangle", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "cc" |
||||
version = "1.0.83" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" |
||||
dependencies = [ |
||||
"libc", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "cfg-if" |
||||
version = "1.0.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" |
||||
|
||||
[[package]] |
||||
name = "gimli" |
||||
version = "0.28.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" |
||||
|
||||
[[package]] |
||||
name = "globtest" |
||||
version = "0.1.0" |
||||
dependencies = [ |
||||
"async-recursion", |
||||
"regex", |
||||
"tokio", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "libc" |
||||
version = "0.2.147" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" |
||||
|
||||
[[package]] |
||||
name = "memchr" |
||||
version = "2.6.3" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" |
||||
|
||||
[[package]] |
||||
name = "miniz_oxide" |
||||
version = "0.7.1" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" |
||||
dependencies = [ |
||||
"adler", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "object" |
||||
version = "0.32.1" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" |
||||
dependencies = [ |
||||
"memchr", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "pin-project-lite" |
||||
version = "0.2.13" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" |
||||
|
||||
[[package]] |
||||
name = "proc-macro2" |
||||
version = "1.0.66" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" |
||||
dependencies = [ |
||||
"unicode-ident", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "quote" |
||||
version = "1.0.33" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" |
||||
dependencies = [ |
||||
"proc-macro2", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "regex" |
||||
version = "1.9.5" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" |
||||
dependencies = [ |
||||
"aho-corasick", |
||||
"memchr", |
||||
"regex-automata", |
||||
"regex-syntax", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "regex-automata" |
||||
version = "0.3.8" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" |
||||
dependencies = [ |
||||
"aho-corasick", |
||||
"memchr", |
||||
"regex-syntax", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "regex-syntax" |
||||
version = "0.7.5" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" |
||||
|
||||
[[package]] |
||||
name = "rustc-demangle" |
||||
version = "0.1.23" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" |
||||
|
||||
[[package]] |
||||
name = "syn" |
||||
version = "2.0.31" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" |
||||
dependencies = [ |
||||
"proc-macro2", |
||||
"quote", |
||||
"unicode-ident", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "tokio" |
||||
version = "1.32.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" |
||||
dependencies = [ |
||||
"backtrace", |
||||
"pin-project-lite", |
||||
"tokio-macros", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "tokio-macros" |
||||
version = "2.1.0" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" |
||||
dependencies = [ |
||||
"proc-macro2", |
||||
"quote", |
||||
"syn", |
||||
] |
||||
|
||||
[[package]] |
||||
name = "unicode-ident" |
||||
version = "1.0.11" |
||||
source = "registry+https://github.com/rust-lang/crates.io-index" |
||||
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" |
@ -0,0 +1,11 @@
|
||||
[package] |
||||
name = "globtest" |
||||
version = "0.1.0" |
||||
edition = "2021" |
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
||||
|
||||
[dependencies] |
||||
async-recursion = "1.0.5" |
||||
regex = "1.9.5" |
||||
tokio = { version = "1.32.0", features = ["rt", "macros", "fs"] } |
@ -0,0 +1,3 @@
|
||||
# GlobTest |
||||
|
||||
Testing making some simple `cp` using Tokio, with wildcard expansion (not actual globs, but close). |
@ -0,0 +1,100 @@
|
||||
use std::path::{Path, PathBuf}; |
||||
|
||||
use regex::Regex; |
||||
|
||||
#[tokio::main(flavor = "current_thread")] |
||||
async fn main() { |
||||
let mut args = std::env::args(); |
||||
args.next(); // jump the command name.
|
||||
|
||||
let source = PathBuf::from(args.next().expect("I want a place to copy from!")); |
||||
let target = PathBuf::from(args.next().expect("I want a place to copy to!")); |
||||
|
||||
println!("From {source:?} to {target:?}"); |
||||
|
||||
match (source.is_file(), source.is_dir()) { |
||||
(true, true) => { |
||||
println!("NO, WAIT! HOW THE THING IS A FILE AND DIR AT THE SAME TIME?!?!"); |
||||
} |
||||
(true, false) => { |
||||
println!("Source is file"); |
||||
copy_file(&source, &target).await; |
||||
} |
||||
(false, true) => { |
||||
println!("Source is a whole directory"); |
||||
copy_dir(&source, &target).await; |
||||
} |
||||
(false, false) => { |
||||
println!("Source is not a file or a directory"); |
||||
copy_magic(&source, &target).await |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// Magical copy
|
||||
async fn copy_magic(source: &Path, target: &Path) { |
||||
if let Some(name) = source.file_name() { |
||||
if name.to_str().unwrap().contains('*') { |
||||
copy_mask(source, target).await; |
||||
} else { |
||||
println!("Source is not a file, not a dir and it doesn't have a mask."); |
||||
println!("I think you're nuts"); |
||||
} |
||||
} |
||||
} |
||||
|
||||
async fn copy_mask(source: &Path, target: &Path) { |
||||
let mask = source.file_name().unwrap(); |
||||
let source = source.parent().unwrap(); |
||||
let re = Regex::new(&mask.to_str().unwrap().replace("*", ".*")).unwrap(); |
||||
|
||||
let mut reader = tokio::fs::read_dir(&source).await.unwrap(); |
||||
while let Ok(Some(entry)) = reader.next_entry().await { |
||||
let entry = entry.path(); |
||||
if entry.is_file() { |
||||
if let Some(name) = entry.file_name() { |
||||
// does the name match the mask?
|
||||
if re.is_match(name.to_str().unwrap()) { |
||||
copy_file(&source.join(name), target).await; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// Make a copy of a directory
|
||||
#[async_recursion::async_recursion] |
||||
async fn copy_dir(source: &Path, target: &Path) { |
||||
if !target.is_dir() { |
||||
println!("Can't copy a whole directory to something that it is NOT a directory!"); |
||||
return; |
||||
} |
||||
|
||||
let mut reader = tokio::fs::read_dir(&source).await.unwrap(); |
||||
while let Ok(Some(entry)) = reader.next_entry().await { |
||||
let entry = entry.path(); |
||||
if entry.is_file() { |
||||
copy_file(&entry, &target).await; |
||||
} else { |
||||
let name = entry.file_name().unwrap(); |
||||
let target = target.join(name); |
||||
tokio::fs::create_dir_all(&target).await.unwrap(); |
||||
copy_dir(&entry, &target).await; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// Make a copy of a file.
|
||||
async fn copy_file(source: &Path, target: &Path) { |
||||
if target.is_dir() { |
||||
println!("Copying to a directory"); |
||||
let filename = source.file_name().unwrap(); // after all, it IS a file
|
||||
let target = target.join(filename); |
||||
println!("Copying from {:?} to {:?}", source, target); |
||||
tokio::fs::copy(source, target).await.unwrap(); |
||||
} else { |
||||
println!("Assuming the destination is already the filename"); |
||||
println!("Copying from {:?} to {:?}", source, target); |
||||
tokio::fs::copy(source, target).await.unwrap(); |
||||
} |
||||
} |
Loading…
Reference in new issue