1use crate::directory::FatDirectory;
6use crate::file::FatFile;
7use crate::filesystem::{FatFilesystem, FatFilesystemInner};
8use std::ops::Deref;
9use std::sync::{Arc, Weak};
10use zx::Status;
11
12pub trait Node {
13 fn attach(
15 &self,
16 parent: Arc<FatDirectory>,
17 name: &str,
18 fs: &FatFilesystemInner,
19 ) -> Result<(), Status>;
20
21 fn detach<'a>(&self, fs: &'a FatFilesystemInner);
23
24 fn open_ref<'a>(&'a self, fs: &'a FatFilesystemInner) -> Result<(), Status>;
26
27 fn close_ref(&self, fs: &FatFilesystemInner);
29
30 fn shut_down(&self, fs: &FatFilesystemInner) -> Result<(), Status>;
33
34 fn flush_dir_entry(&self, fs: &FatFilesystemInner) -> Result<(), Status>;
36
37 fn did_delete(&self);
39}
40
41#[derive(Clone, Debug)]
42pub enum FatNode {
45 Dir(Arc<FatDirectory>),
46 File(Arc<FatFile>),
47}
48
49impl FatNode {
50 pub fn downgrade(&self) -> WeakFatNode {
52 match self {
53 FatNode::Dir(a) => WeakFatNode::Dir(Arc::downgrade(a)),
54 FatNode::File(b) => WeakFatNode::File(Arc::downgrade(b)),
55 }
56 }
57
58 pub fn as_node(&self) -> &(dyn Node + 'static) {
59 match self {
60 FatNode::Dir(ref a) => a.as_ref() as &dyn Node,
61 FatNode::File(ref b) => b.as_ref() as &dyn Node,
62 }
63 }
64}
65
66impl<'a> Deref for FatNode {
67 type Target = dyn Node;
68
69 fn deref(&self) -> &Self::Target {
70 self.as_node()
71 }
72}
73
74#[derive(Debug)]
76pub enum WeakFatNode {
77 Dir(Weak<FatDirectory>),
78 File(Weak<FatFile>),
79}
80
81impl WeakFatNode {
82 pub fn upgrade(&self) -> Option<FatNode> {
85 match self {
86 WeakFatNode::Dir(a) => a.upgrade().map(|val| FatNode::Dir(val)),
87 WeakFatNode::File(b) => b.upgrade().map(|val| FatNode::File(val)),
88 }
89 }
90}
91
92pub struct Closer<'a> {
96 filesystem: &'a FatFilesystem,
97 nodes: std::vec::Vec<FatNode>,
98}
99
100impl<'a> Closer<'a> {
101 pub fn new(filesystem: &'a FatFilesystem) -> Self {
102 Closer { filesystem, nodes: Vec::new() }
103 }
104
105 pub fn add(&mut self, node: FatNode) -> FatNode {
106 self.nodes.push(node.clone());
107 node
108 }
109}
110
111impl Drop for Closer<'_> {
112 fn drop(&mut self) {
113 let lock = self.filesystem.lock();
114 self.nodes.drain(..).for_each(|n: FatNode| n.close_ref(&lock));
115 }
116}