1use std::fs::ReadDir;
8use std::iter::Iterator as _;
9use std::{fs, result};
10
11use ion::class::Reflector;
12use ion::conversions::ToValue as _;
13use ion::{ClassDefinition as _, Context, Iterator, JSIterator, Result, Value, js_class};
14
15use crate::fs::{Metadata, metadata_error};
16
17#[js_class]
18pub struct DirEntry {
19 reflector: Reflector,
20 #[trace(no_trace)]
21 entry: fs::DirEntry,
22}
23
24#[js_class]
25impl DirEntry {
26 pub fn name(&self) -> String {
27 self.entry.file_name().to_string_lossy().into_owned()
28 }
29
30 pub fn path(&self) -> String {
31 self.entry.path().to_string_lossy().into_owned()
32 }
33
34 pub fn metadata(&self) -> Result<Metadata> {
35 self.entry
36 .metadata()
37 .as_ref()
38 .map(Metadata::new)
39 .map_err(|err| metadata_error(&self.path(), err))
40 }
41}
42
43pub(crate) struct DirIterator(ReadDir);
44
45impl DirIterator {
46 pub(crate) fn new_iterator(dir: ReadDir) -> Iterator {
47 Iterator::new(DirIterator(dir), &Value::undefined_handle())
48 }
49}
50
51impl JSIterator for DirIterator {
52 fn next_value<'cx>(&mut self, cx: &'cx Context, _: &Value<'cx>) -> Option<Value<'cx>> {
53 let entry = self.0.find(result::Result::is_ok).transpose().unwrap()?;
54 let entry = Box::new(DirEntry { reflector: Reflector::new(), entry });
55 Some(DirEntry::new_object(cx, entry).as_value(cx))
56 }
57}