1use crate::error::{ClientResultExt, ZeroFsError};
2use crate::session::{FidGuard, Session};
3use crate::types::{Metadata, SetAttrs};
4use std::sync::Arc;
5use std::sync::atomic::{AtomicBool, Ordering};
6
7pub struct File {
12 session: Arc<Session>,
13 guard: FidGuard,
14 closed: AtomicBool,
15 path: String,
16}
17
18impl std::fmt::Debug for File {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 f.debug_struct("File")
21 .field("path", &self.path)
22 .field("closed", &self.closed.load(Ordering::Relaxed))
23 .finish_non_exhaustive()
24 }
25}
26
27impl File {
28 pub(crate) fn new(session: Arc<Session>, guard: FidGuard, path: String) -> Arc<Self> {
29 Arc::new(Self {
30 session,
31 guard,
32 closed: AtomicBool::new(false),
33 path,
34 })
35 }
36
37 fn fid(&self) -> Result<u32, ZeroFsError> {
38 if self.closed.load(Ordering::Acquire) {
39 return Err(ZeroFsError::Closed);
40 }
41 Ok(self.guard.fid())
42 }
43
44 #[cfg(feature = "tokio-io")]
47 pub(crate) fn max_read_chunk(&self) -> u32 {
48 self.session.client.max_io()
49 }
50
51 pub async fn read_at(&self, offset: u64, len: u32) -> Result<bytes::Bytes, ZeroFsError> {
54 self.session
55 .client
56 .read_bytes(self.fid()?, offset, len)
57 .await
58 .ctx(&self.path)
59 }
60
61 pub async fn write_at(&self, offset: u64, data: &[u8]) -> Result<(), ZeroFsError> {
64 self.session
65 .write_all(self.fid()?, offset, data, &self.path)
66 .await
67 }
68
69 pub async fn metadata(&self) -> Result<Metadata, ZeroFsError> {
71 let stat = self.session.stat_fid(self.fid()?, &self.path).await?;
72 Ok(Metadata::from_stat(&stat))
73 }
74
75 pub async fn set_len(&self, size: u64) -> Result<(), ZeroFsError> {
77 self.set_attr(SetAttrs {
78 size: Some(size),
79 ..Default::default()
80 })
81 .await?;
82 Ok(())
83 }
84
85 pub async fn set_attr(&self, attrs: SetAttrs) -> Result<Metadata, ZeroFsError> {
87 let stat = self
88 .session
89 .setattr_fid(self.fid()?, &attrs, &self.path)
90 .await?;
91 Ok(Metadata::from_stat(&stat))
92 }
93
94 pub async fn sync_all(&self) -> Result<(), ZeroFsError> {
99 self.session
100 .client
101 .fsync(self.fid()?, 0)
102 .await
103 .ctx(&self.path)
104 }
105
106 pub async fn sync_data(&self) -> Result<(), ZeroFsError> {
108 self.session
109 .client
110 .fsync(self.fid()?, 1)
111 .await
112 .ctx(&self.path)
113 }
114
115 pub async fn close(&self) {
118 self.closed.store(true, Ordering::Release);
119 }
120
121 #[cfg(feature = "tokio-io")]
126 pub fn cursor(self: &Arc<File>) -> crate::io::FileCursor {
127 crate::io::FileCursor::new(Arc::clone(self))
128 }
129}