1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
use std::ffi::OsString; use std::path::{Path, PathBuf}; use crate::base; use crate::context::Context; use crate::error::{Error, Result}; pub fn read<P: AsRef<Path>>(context: &Context, path: P) -> Result<Vec<u8>> { let file = context.root().open_file(path.as_ref())?; Ok(file.content().into()) } pub fn read_to_string<P: AsRef<Path>>(context: &Context, path: P) -> Result<String> { let bytes = read(context, path)?; String::from_utf8(bytes).map_err(|error| Error::FromUtf8Error(error)) } pub fn read_link<'a, P: AsRef<Path>>(context: &'a Context, path: P) -> Result<PathBuf> { context .root() .open_link(path) .map(|link| link.target().into()) } pub fn read_dir<'a, P: AsRef<Path>>(context: &'a Context, path: P) -> Result<ReadDir<'a>> { let path = path.as_ref(); let dir = context.root().open_dir(path)?; Ok(ReadDir { root: path.into(), dir_iter: dir.iter(), }) } pub struct ReadDir<'a> { root: PathBuf, dir_iter: base::DirIter<'a>, } impl<'a> Iterator for ReadDir<'a> { type Item = Result<DirEntry<'a>>; fn next(&mut self) -> Option<Self::Item> { if let Some(name) = self.dir_iter.next() { return Some(Ok(DirEntry { root: self.root.clone(), name, })); } None } } pub struct DirEntry<'a> { root: PathBuf, name: &'a OsString, } impl<'a> DirEntry<'a> { pub fn path(&self) -> PathBuf { self.root.join(self.file_name()) } pub fn file_name(&self) -> OsString { self.name.clone() } }