Skip to content

Commit 7875cda

Browse files
committed
test: add std and tokio tests
Also fixed examples.
1 parent 6aeb68f commit 7875cda

File tree

5 files changed

+568
-30
lines changed

5 files changed

+568
-30
lines changed

README.md

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,32 +25,35 @@ The loop is the glue between coroutines and runtimes. It makes the coroutine pro
2525
### Read a directory synchronously
2626

2727
```rust,ignore
28-
use io_fs::{coroutines::ReadDir, runtimes::std::handle};
28+
use std::{path::PathBuf};
2929
30-
let mut output = None;
30+
use io_fs::{coroutines::read_dir::ReadDir, error::FsResult, runtimes::std::handle};
31+
32+
let mut arg = None;
3133
let mut coroutine = ReadDir::new("/tmp");
3234
33-
let entries = loop {
34-
match coroutine.resume(output) {
35-
Ok(entries) => break entries,
36-
Err(io) => output = Some(handle(io).unwrap()),
35+
let paths = loop {
36+
match coroutine.resume(arg) {
37+
FsResult::Ok(paths) => break paths,
38+
FsResult::Err(err) => panic!("{err}"),
39+
FsResult::Io(io) => arg = Some(handle(io).unwrap()),
3740
}
3841
};
3942
40-
println!("Entries inside /tmp:");
43+
println!("Entries inside {}:", path.display());
4144
4245
for path in paths {
4346
println!(" - {}", path.display());
4447
}
4548
```
4649

47-
*See complete example at [./examples/std-read-dir.rs](https://github.com/pimalaya/io-fs/blob/master/examples/std-read-dir.rs).*
50+
*See complete examples at [./examples](https://github.com/pimalaya/io-fs/blob/master/examples).*
4851

4952
### More examples
5053

5154
Have a look at projects built on the top of this library:
5255

53-
- [io-vdir](https://github.com/pimalaya/io-vdir): Set of I/O-free Rust coroutines and runtimes to manage [Vdir](https://vdirsyncer.pimutils.org/en/stable/vdir.html) filesystems.
56+
- [io-vdir](https://github.com/pimalaya/io-vdir): Set of I/O-free Rust coroutines to manage [Vdir](https://vdirsyncer.pimutils.org/en/stable/vdir.html) filesystems.
5457

5558
## Sponsoring
5659

examples/std-read-dir.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,33 @@
11
#![cfg(feature = "std")]
22

3-
use std::io::{stdin, stdout, Write as _};
3+
use std::{
4+
env,
5+
io::{stdin, stdout, Write as _},
6+
path::PathBuf,
7+
};
48

5-
use io_fs::{coroutines::ReadDir, runtimes::std::handle};
9+
use io_fs::{coroutines::read_dir::ReadDir, error::FsResult, runtimes::std::handle};
610

711
fn main() {
8-
env_logger::init();
12+
let _ = env_logger::try_init();
913

10-
let path = read_line("Which directory to read?");
14+
let path: PathBuf = match env::var("DIR") {
15+
Ok(dir) => dir.into(),
16+
Err(_) => read_line("Directory to read?").into(),
17+
};
1118

12-
let mut output = None;
19+
let mut arg = None;
1320
let mut coroutine = ReadDir::new(&path);
1421

1522
let paths = loop {
16-
match coroutine.resume(output) {
17-
Ok(paths) => break paths,
18-
Err(io) => output = Some(handle(io).unwrap()),
23+
match coroutine.resume(arg) {
24+
FsResult::Ok(paths) => break paths,
25+
FsResult::Err(err) => panic!("{err}"),
26+
FsResult::Io(io) => arg = Some(handle(io).unwrap()),
1927
}
2028
};
2129

22-
println!("Entries inside {path}:");
30+
println!("Entries inside {}:", path.display());
2331

2432
for path in paths {
2533
println!(" - {}", path.display());

examples/tokio-create-many-files.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,37 @@
11
#![cfg(feature = "tokio")]
22

33
use std::{
4+
env,
45
io::{stdin, stdout, Write as _},
56
time::Instant,
67
};
78

8-
use io_fs::{coroutines::CreateFiles, runtimes::tokio::handle};
9+
use io_fs::{coroutines::create_files::CreateFiles, error::FsResult, runtimes::tokio::handle};
910
use tempdir::TempDir;
1011

1112
#[tokio::main]
1213
async fn main() {
13-
env_logger::init();
14+
let _ = env_logger::try_init();
1415

15-
let tmp = TempDir::new("tokio-create-files").unwrap();
16+
let tmp = TempDir::new("tokio-create-many-files").unwrap();
1617

17-
let n = read_line("How many temp files to create?")
18-
.parse::<usize>()
19-
.unwrap();
18+
let n: usize = match env::var("N") {
19+
Ok(n) => n.parse().unwrap(),
20+
Err(_) => read_line("How many temp files to create?").parse().unwrap(),
21+
};
2022

2123
let start = Instant::now();
2224

23-
let mut output = None;
24-
let mut coroutine = CreateFiles::new(
25-
(0..n).map(|n| (tmp.path().join(n.to_string()), b"Hello, world!".to_vec())),
26-
);
25+
let mut arg = None;
26+
let mut coroutine =
27+
CreateFiles::new((0..n).map(|n| (tmp.path().join(n.to_string()), *b"Hello, world!")));
2728

28-
while let Err(io) = coroutine.resume(output) {
29-
output = Some(handle(io).await.unwrap());
29+
loop {
30+
match coroutine.resume(arg) {
31+
FsResult::Ok(()) => break,
32+
FsResult::Err(err) => panic!("{err}"),
33+
FsResult::Io(io) => arg = Some(handle(io).await.unwrap()),
34+
}
3035
}
3136

3237
let duration = start.elapsed();

tests/std.rs

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
#![cfg(feature = "std")]
2+
3+
use std::collections::{HashMap, HashSet};
4+
5+
use io_fs::{
6+
coroutines::{
7+
create_dir::CreateDir, create_dirs::CreateDirs, create_file::CreateFile,
8+
create_files::CreateFiles, read_dir::ReadDir, read_file::ReadFile, read_files::ReadFiles,
9+
remove_dir::RemoveDir, remove_dirs::RemoveDirs, remove_file::RemoveFile,
10+
remove_files::RemoveFiles, rename::Rename,
11+
},
12+
error::FsResult,
13+
runtimes::std::handle,
14+
};
15+
use tempdir::TempDir;
16+
17+
#[test]
18+
fn std() {
19+
let _ = env_logger::try_init();
20+
21+
let workdir = TempDir::new("test-fs-std").unwrap();
22+
23+
// create single directory
24+
25+
let mut arg = None;
26+
let mut coroutine = CreateDir::new(workdir.path().join("dir1"));
27+
28+
loop {
29+
match coroutine.resume(arg) {
30+
FsResult::Ok(()) => break,
31+
FsResult::Err(err) => panic!("{err}"),
32+
FsResult::Io(io) => arg = Some(handle(io).unwrap()),
33+
}
34+
}
35+
36+
assert!(workdir.path().join("dir1").is_dir());
37+
38+
// create multiple directories
39+
40+
let mut arg = None;
41+
let mut coroutine = CreateDirs::new([workdir.path().join("dir2"), workdir.path().join("dir3")]);
42+
43+
loop {
44+
match coroutine.resume(arg) {
45+
FsResult::Ok(()) => break,
46+
FsResult::Err(err) => panic!("{err}"),
47+
FsResult::Io(io) => arg = Some(handle(io).unwrap()),
48+
}
49+
}
50+
51+
assert!(workdir.path().join("dir2").is_dir());
52+
assert!(workdir.path().join("dir3").is_dir());
53+
54+
// create single file
55+
56+
let mut arg = None;
57+
let mut coroutine = CreateFile::new(workdir.path().join("dir1").join("file1"), *b"file1");
58+
59+
loop {
60+
match coroutine.resume(arg) {
61+
FsResult::Ok(()) => break,
62+
FsResult::Err(err) => panic!("{err}"),
63+
FsResult::Io(io) => arg = Some(handle(io).unwrap()),
64+
}
65+
}
66+
67+
assert!(workdir.path().join("dir1").join("file1").is_file());
68+
69+
// create multiple files
70+
71+
let mut arg = None;
72+
let mut coroutine = CreateFiles::new([
73+
(workdir.path().join("dir2").join("file2"), *b"file2"),
74+
(workdir.path().join("dir2").join("file3"), *b"file3"),
75+
]);
76+
77+
loop {
78+
match coroutine.resume(arg) {
79+
FsResult::Ok(()) => break,
80+
FsResult::Err(err) => panic!("{err}"),
81+
FsResult::Io(io) => arg = Some(handle(io).unwrap()),
82+
}
83+
}
84+
85+
assert!(workdir.path().join("dir2").join("file2").is_file());
86+
assert!(workdir.path().join("dir2").join("file3").is_file());
87+
88+
// read directory
89+
90+
let mut arg = None;
91+
let mut coroutine = ReadDir::new(workdir.path().join("dir1"));
92+
93+
let paths = loop {
94+
match coroutine.resume(arg) {
95+
FsResult::Ok(paths) => break paths,
96+
FsResult::Err(err) => panic!("{err}"),
97+
FsResult::Io(io) => arg = Some(handle(io).unwrap()),
98+
}
99+
};
100+
101+
let expected_paths = HashSet::from_iter([workdir.path().join("dir1").join("file1")]);
102+
103+
assert_eq!(paths, expected_paths);
104+
105+
arg = None;
106+
coroutine = ReadDir::new(workdir.path().join("dir2"));
107+
108+
let paths = loop {
109+
match coroutine.resume(arg) {
110+
FsResult::Ok(paths) => break paths,
111+
FsResult::Err(err) => panic!("{err}"),
112+
FsResult::Io(io) => arg = Some(handle(io).unwrap()),
113+
}
114+
};
115+
116+
let expected_paths = HashSet::from_iter([
117+
workdir.path().join("dir2").join("file2"),
118+
workdir.path().join("dir2").join("file3"),
119+
]);
120+
121+
assert_eq!(paths, expected_paths);
122+
123+
arg = None;
124+
coroutine = ReadDir::new(workdir.path().join("dir3"));
125+
126+
let paths = loop {
127+
match coroutine.resume(arg) {
128+
FsResult::Ok(paths) => break paths,
129+
FsResult::Err(err) => panic!("{err}"),
130+
FsResult::Io(io) => arg = Some(handle(io).unwrap()),
131+
}
132+
};
133+
134+
assert!(paths.is_empty());
135+
136+
// read single file
137+
138+
let mut arg = None;
139+
let mut coroutine = ReadFile::new(workdir.path().join("dir1").join("file1"));
140+
141+
let contents = loop {
142+
match coroutine.resume(arg) {
143+
FsResult::Ok(contents) => break contents,
144+
FsResult::Err(err) => panic!("{err}"),
145+
FsResult::Io(io) => arg = Some(handle(io).unwrap()),
146+
}
147+
};
148+
149+
assert_eq!(b"file1", contents.as_slice());
150+
151+
// read multiple files
152+
153+
let mut arg = None;
154+
let mut coroutine = ReadFiles::new([
155+
workdir.path().join("dir2").join("file2"),
156+
workdir.path().join("dir2").join("file3"),
157+
]);
158+
159+
let contents = loop {
160+
match coroutine.resume(arg) {
161+
FsResult::Ok(contents) => break contents,
162+
FsResult::Err(err) => panic!("{err}"),
163+
FsResult::Io(io) => arg = Some(handle(io).unwrap()),
164+
}
165+
};
166+
167+
let expected_contents = HashMap::from_iter([
168+
(workdir.path().join("dir2").join("file2"), b"file2".to_vec()),
169+
(workdir.path().join("dir2").join("file3"), b"file3".to_vec()),
170+
]);
171+
172+
assert_eq!(contents, expected_contents);
173+
174+
// rename
175+
176+
let mut arg = None;
177+
let mut coroutine = Rename::new(Some((
178+
workdir.path().join("dir2").join("file3"),
179+
workdir.path().join("dir3").join("file3"),
180+
)));
181+
182+
loop {
183+
match coroutine.resume(arg) {
184+
FsResult::Ok(()) => break,
185+
FsResult::Err(err) => panic!("{err}"),
186+
FsResult::Io(io) => arg = Some(handle(io).unwrap()),
187+
}
188+
}
189+
190+
assert_eq!(false, workdir.path().join("dir2").join("file3").is_file());
191+
assert_eq!(true, workdir.path().join("dir3").join("file3").is_file());
192+
193+
// remove single file
194+
195+
let mut arg = None;
196+
let mut coroutine = RemoveFile::new(workdir.path().join("dir3").join("file3"));
197+
198+
loop {
199+
match coroutine.resume(arg) {
200+
FsResult::Ok(()) => break,
201+
FsResult::Err(err) => panic!("{err}"),
202+
FsResult::Io(io) => arg = Some(handle(io).unwrap()),
203+
}
204+
}
205+
206+
assert_eq!(false, workdir.path().join("dir3").join("file3").is_file());
207+
208+
// remove multiple files
209+
210+
let mut arg = None;
211+
let mut coroutine = RemoveFiles::new([
212+
workdir.path().join("dir1").join("file1"),
213+
workdir.path().join("dir2").join("file2"),
214+
]);
215+
216+
loop {
217+
match coroutine.resume(arg) {
218+
FsResult::Ok(()) => break,
219+
FsResult::Err(err) => panic!("{err}"),
220+
FsResult::Io(io) => arg = Some(handle(io).unwrap()),
221+
}
222+
}
223+
224+
assert_eq!(false, workdir.path().join("dir1").join("file1").is_file());
225+
assert_eq!(false, workdir.path().join("dir2").join("file2").is_file());
226+
227+
// remove single directory
228+
229+
let mut arg = None;
230+
let mut coroutine = RemoveDir::new(workdir.path().join("dir3"));
231+
232+
loop {
233+
match coroutine.resume(arg) {
234+
FsResult::Ok(()) => break,
235+
FsResult::Err(err) => panic!("{err}"),
236+
FsResult::Io(io) => arg = Some(handle(io).unwrap()),
237+
}
238+
}
239+
240+
assert_eq!(false, workdir.path().join("dir3").is_dir());
241+
242+
// remove multiple directories
243+
244+
let mut arg = None;
245+
let mut coroutine = RemoveDirs::new([workdir.path().join("dir1"), workdir.path().join("dir2")]);
246+
247+
loop {
248+
match coroutine.resume(arg) {
249+
FsResult::Ok(()) => break,
250+
FsResult::Err(err) => panic!("{err}"),
251+
FsResult::Io(io) => arg = Some(handle(io).unwrap()),
252+
}
253+
}
254+
255+
assert_eq!(false, workdir.path().join("dir1").is_dir());
256+
assert_eq!(false, workdir.path().join("dir2").is_dir());
257+
258+
// end
259+
260+
workdir.close().unwrap()
261+
}

0 commit comments

Comments
 (0)