1use alloc::sync::Arc;
2use core::ops::Deref;
3
4use axpoll::Pollable;
5
6use super::NodeOps;
7use crate::{VfsError, VfsResult};
8
9pub trait FileNodeOps: NodeOps + Pollable {
10 fn read_at(&self, buf: &mut [u8], offset: u64) -> VfsResult<usize>;
12
13 fn write_at(&self, buf: &[u8], offset: u64) -> VfsResult<usize>;
15
16 fn append(&self, buf: &[u8]) -> VfsResult<(usize, u64)>;
21
22 fn set_len(&self, len: u64) -> VfsResult<()>;
24
25 fn set_symlink(&self, target: &str) -> VfsResult<()>;
27
28 fn ioctl(&self, _cmd: u32, _arg: usize) -> VfsResult<usize> {
30 Err(VfsError::NotATty)
31 }
32}
33
34#[repr(transparent)]
35pub struct FileNode(Arc<dyn FileNodeOps>);
36
37impl Deref for FileNode {
38 type Target = dyn FileNodeOps;
39
40 fn deref(&self) -> &Self::Target {
41 &*self.0
42 }
43}
44
45impl From<FileNode> for Arc<dyn NodeOps> {
46 fn from(node: FileNode) -> Self {
47 node.0.clone()
48 }
49}
50
51impl FileNode {
52 pub fn new(ops: Arc<dyn FileNodeOps>) -> Self {
53 Self(ops)
54 }
55
56 pub fn inner(&self) -> &Arc<dyn FileNodeOps> {
57 &self.0
58 }
59
60 pub fn downcast<T: FileNodeOps>(self: &Arc<Self>) -> VfsResult<Arc<T>> {
61 self.0
62 .clone()
63 .into_any()
64 .downcast()
65 .map_err(|_| VfsError::InvalidInput)
66 }
67}