1use std::{io::Cursor, path::Path};
2
3use crate::{
4 r#async::{BufFut, IoFut},
5 VowFileAsync,
6};
7
8use compio_fs::File;
9use compio_io::{repeat, AsyncReadAtExt, AsyncReadExt, AsyncWriteAtExt};
10
11impl VowFileAsync for File {
12 fn open(path: &Path) -> impl IoFut<Self>
13 where
14 Self: Sized,
15 {
16 async move {
17 compio_fs::OpenOptions::new()
18 .read(true)
19 .write(true)
20 .create(true)
21 .truncate(false)
22 .open(path)
23 .await
24 }
25 }
26
27 fn read(&mut self, buf: Vec<u8>) -> impl BufFut {
28 async move {
29 let res = self.read_to_end_at(buf, 0).await;
30 (res.0.map(|_| ()), res.1)
31 }
32 }
33
34 fn write(&mut self, buf: Vec<u8>) -> impl BufFut {
35 async move {
36 let res = self.write_all_at(buf, 0).await;
37 (res.0, res.1)
38 }
39 }
40
41 fn flush(&mut self) -> impl IoFut<()> {
42 async move {
43 self.sync_data().await?;
44 Ok(())
45 }
46 }
47
48 fn set_len(&mut self, len: u64) -> impl IoFut<()> {
49 async move {
50 let curr_len = self.metadata().await?.len();
51
52 if curr_len > len {
53 let mut this = Cursor::new(self);
54 this.set_position(len);
55 compio_io::copy(&mut repeat(0).take(curr_len - len), &mut this).await?;
56 }
57
58 Ok(())
59 }
60 }
61}
62
63#[cfg(test)]
64#[cfg(feature = "backend-compio")]
65mod test {
66 use compio_io::AsyncWriteAtExt;
67
68 use crate::VowFileAsync;
69
70 #[compio::test]
71 async fn test_write() {
72 let mut file = compio_fs::File::create("/tmp/test.txt").await.unwrap();
73 file.write_all_at("12345678", 0).await.unwrap();
74 let read = compio_fs::read("/tmp/test.txt").await.unwrap();
75 assert_eq!(read, b"12345678");
76
77 file.set_len(4).await.unwrap();
78 let read = compio_fs::read("/tmp/test.txt").await.unwrap();
79 assert_eq!(read, b"1234\0\0\0\0");
80 }
81}