1use core::fmt;
2use crate::{FsNode, FileSystem};
3
4#[cfg(feature = "no_std")]
5use crate::std::vec::Vec;
6
7impl FileSystem {
8 pub fn iter_root<'a>(&'a self) -> impl Iterator<Item = DirEntry<'a>> + 'a {
10 let files = &self.files;
11 let mut entries = Vec::new();
12
13 let mut entries_iter = self.files
14 .iter()
15 .enumerate()
16 .map(|(i, node)| DirEntry { node, files, index: i + 1 });
17
18 while let Some(entry) = entries_iter.next() {
19 recursive_remove(&entry, &mut entries_iter);
20
21 entries.push(entry);
22 }
23
24 entries.into_iter()
25 }
26
27 pub fn get_child(&self, child_name: &str) -> Option<DirEntry> {
28 self.iter_root()
29 .find(|entry| {
30 match entry.node {
31 FsNode::Directory { name, .. } | FsNode::File { name, .. }
32 if name == child_name => true,
33 _ => false
34 }
35 })
36 }
37}
38
39#[derive(Clone, Copy)]
41pub struct DirEntry<'a> {
42 node: &'a FsNode,
44
45 files: &'a [FsNode],
47
48 index: usize,
50}
51
52impl<'a> fmt::Debug for DirEntry<'a> {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54 fmt::Debug::fmt(&self.node, f)
55 }
56}
57
58fn recursive_remove<'a>(entry: &DirEntry, iter: &mut impl Iterator<Item = DirEntry<'a>>) {
59 match entry.node {
60 &FsNode::Directory { end_index, .. } => {
61 for _ in 1..(end_index as usize - entry.index) {
62 iter.next();
63 }
64 }
65 _ => {}
66 }
67}
68
69impl<'a> DirEntry<'a> {
70 pub fn is_dir(&self) -> bool {
71 match self.node {
72 FsNode::Directory { .. } => true,
73 FsNode::File { .. } => false,
74 }
75 }
76
77 pub fn is_file(&self) -> bool {
78 match self.node {
79 FsNode::Directory { .. } => false,
80 FsNode::File { .. } => true,
81 }
82 }
83
84 pub fn entry_name(&self) -> &'a str {
85 match self.node {
86 FsNode::File { name, .. } | FsNode::Directory { name, .. } => &name,
87 }
88 }
89
90 pub fn iter_dir(&self) -> Option<impl Iterator<Item = DirEntry<'a>> + 'a> {
91 match self.node {
92 FsNode::Directory { end_index, .. } => {
93 let files = self.files;
94 let index = self.index;
95 let end_index = *end_index as usize;
96
97 let mut entries = Vec::new();
98 let mut entries_iter =
99 files[index..end_index - 1]
100 .iter()
101 .enumerate()
102 .map(|(i, node)| DirEntry { node, files, index: index + i + 1 });
103
104 while let Some(entry) = entries_iter.next() {
105 recursive_remove(&entry, &mut entries_iter);
106 entries.push(entry);
107 }
108
109 Some(entries.into_iter())
110 },
111 FsNode::File { .. } => None,
112 }
113 }
114
115 pub fn get_child(&self, child_name: &str) -> Option<DirEntry<'a>> {
116 self.iter_dir()?
117 .find(|entry| {
118 match entry.node {
119 FsNode::Directory { name, .. } | FsNode::File { name, .. }
120 if name == child_name => true,
121 _ => false
122 }
123 })
124 }
125
126 pub fn as_file(&self) -> Option<File> {
127 match self.node {
128 &FsNode::File { offset, size, .. } => Some(File { offset, size }),
129 FsNode::Directory { .. } => None
130 }
131 }
132}
133
134#[derive(Debug, Clone, Copy)]
137pub struct File {
138 pub offset: u32,
139 pub size: u32
140}