Browse Source

Playing with tokio, copy, and wildcards

master
Julio Biason 8 months ago
parent
commit
100f4858c3
  1. 211
      globtest/Cargo.lock
  2. 11
      globtest/Cargo.toml
  3. 3
      globtest/README.md
  4. 100
      globtest/src/main.rs

211
globtest/Cargo.lock generated

@ -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"

11
globtest/Cargo.toml

@ -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"] }

3
globtest/README.md

@ -0,0 +1,3 @@
# GlobTest
Testing making some simple `cp` using Tokio, with wildcard expansion (not actual globs, but close).

100
globtest/src/main.rs

@ -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…
Cancel
Save