From 2304b13ec4ab6337b50bceb75603f86faa662fd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Harabie=C5=84?= Date: Tue, 12 Jun 2018 00:07:30 +0200 Subject: [PATCH] Take immutable self reference in Dir methods Dir methods do not change Dir object itself. They usually clone inner stream so no change really happens self struct. Underlying partition is modified but it does not have to affect API. For example see std::fs::File::set_len. This change greatly simplifies rename API usage. --- README.md | 2 +- examples/cat.rs | 2 +- examples/ls.rs | 2 +- src/dir.rs | 26 +++++++++++++------------- src/dir_entry.rs | 6 +++--- tests/read.rs | 8 ++++---- tests/write.rs | 21 ++++++++++----------- 7 files changed, 33 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index cb5bd71..73ee049 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ You can start using library now: let img_file = File::open("fat.img")?; let mut buf_stream = fatfs::BufStream::new(img_file); let fs = fatfs::FileSystem::new(&mut buf_stream, fatfs::FsOptions::new())?; - let mut root_dir = fs.root_dir(); + let root_dir = fs.root_dir(); let mut file = root_dir.create_file("hello.txt")?; file.write_all(b"Hello World!")?; diff --git a/examples/cat.rs b/examples/cat.rs index e529814..fbf8be8 100644 --- a/examples/cat.rs +++ b/examples/cat.rs @@ -10,7 +10,7 @@ fn main() -> io::Result<()> { let file = File::open("resources/fat32.img")?; let mut buf_rdr = BufStream::new(file); let fs = FileSystem::new(&mut buf_rdr, FsOptions::new())?; - let mut root_dir = fs.root_dir(); + let root_dir = fs.root_dir(); let mut file = root_dir.open_file(&env::args().nth(1).unwrap())?; let mut buf = vec![]; file.read_to_end(&mut buf)?; diff --git a/examples/ls.rs b/examples/ls.rs index 16989f1..d519388 100644 --- a/examples/ls.rs +++ b/examples/ls.rs @@ -27,7 +27,7 @@ fn main() -> io::Result<()> { let file = File::open("resources/fat32.img")?; let mut buf_rdr = BufStream::new(file); let fs = FileSystem::new(&mut buf_rdr, FsOptions::new())?; - let mut root_dir = fs.root_dir(); + let root_dir = fs.root_dir(); let dir = match env::args().nth(1) { None => root_dir, Some(ref path) if path == "." => root_dir, diff --git a/src/dir.rs b/src/dir.rs index 37864e6..ef82369 100644 --- a/src/dir.rs +++ b/src/dir.rs @@ -100,7 +100,7 @@ impl <'a, 'b> Dir<'a, 'b> { } } - fn find_entry(&mut self, name: &str, is_dir: Option, mut short_name_gen: Option<&mut ShortNameGenerator>) -> io::Result> { + fn find_entry(&self, name: &str, is_dir: Option, mut short_name_gen: Option<&mut ShortNameGenerator>) -> io::Result> { for r in self.iter() { let e = r?; // compare name ignoring case @@ -120,7 +120,7 @@ impl <'a, 'b> Dir<'a, 'b> { } /// Opens existing directory - pub fn open_dir(&mut self, path: &str) -> io::Result { + pub fn open_dir(&self, path: &str) -> io::Result { let (name, rest_opt) = split_path(path); let e = self.find_entry(name, Some(true), None)?; match rest_opt { @@ -130,7 +130,7 @@ impl <'a, 'b> Dir<'a, 'b> { } /// Opens existing file. - pub fn open_file(&mut self, path: &str) -> io::Result> { + pub fn open_file(&self, path: &str) -> io::Result> { // traverse path let (name, rest_opt) = split_path(path); if let Some(rest) = rest_opt { @@ -143,7 +143,7 @@ impl <'a, 'b> Dir<'a, 'b> { } /// Creates new file or opens existing without truncating. - pub fn create_file(&mut self, path: &str) -> io::Result> { + pub fn create_file(&self, path: &str) -> io::Result> { // traverse path let (name, rest_opt) = split_path(path); if let Some(rest) = rest_opt { @@ -167,7 +167,7 @@ impl <'a, 'b> Dir<'a, 'b> { } /// Creates new directory or opens existing. - pub fn create_dir(&mut self, path: &str) -> io::Result { + pub fn create_dir(&self, path: &str) -> io::Result { // traverse path let (name, rest_opt) = split_path(path); if let Some(rest) = rest_opt { @@ -202,7 +202,7 @@ impl <'a, 'b> Dir<'a, 'b> { } } - fn is_empty(&mut self) -> io::Result { + fn is_empty(&self) -> io::Result { // check if directory contains no files for r in self.iter() { let e = r?; @@ -219,7 +219,7 @@ impl <'a, 'b> Dir<'a, 'b> { /// /// Make sure there is no reference to this file (no File instance) or filesystem corruption /// can happen. - pub fn remove(&mut self, path: &str) -> io::Result<()> { + pub fn remove(&self, path: &str) -> io::Result<()> { // traverse path let (name, rest_opt) = split_path(path); if let Some(rest) = rest_opt { @@ -255,7 +255,7 @@ impl <'a, 'b> Dir<'a, 'b> { /// Destination directory can be cloned source directory in case of rename without moving operation. /// Make sure there is no reference to this file (no File instance) or filesystem corruption /// can happen. - pub fn rename(&mut self, src_path: &str, dst_dir: &mut Dir, dst_path: &str) -> io::Result<()> { + pub fn rename(&self, src_path: &str, dst_dir: &Dir, dst_path: &str) -> io::Result<()> { // traverse source path let (name, rest_opt) = split_path(src_path); if let Some(rest) = rest_opt { @@ -272,7 +272,7 @@ impl <'a, 'b> Dir<'a, 'b> { self.rename_internal(src_path, dst_dir, dst_path) } - fn rename_internal(&mut self, src_name: &str, dst_dir: &mut Dir, dst_name: &str) -> io::Result<()> { + fn rename_internal(&self, src_name: &str, dst_dir: &Dir, dst_name: &str) -> io::Result<()> { trace!("moving {} to {}", src_name, dst_name); // find existing file let e = self.find_entry(src_name, None, None)?; @@ -300,7 +300,7 @@ impl <'a, 'b> Dir<'a, 'b> { Ok(()) } - fn find_free_entries(&mut self, num_entries: usize) -> io::Result> { + fn find_free_entries(&self, num_entries: usize) -> io::Result> { let mut stream = self.stream.clone(); let mut first_free = 0; let mut num_free = 0; @@ -334,7 +334,7 @@ impl <'a, 'b> Dir<'a, 'b> { } #[cfg(feature = "alloc")] - fn create_lfn_entries(&mut self, name: &str, short_name: &[u8]) -> io::Result<(DirRawStream<'a, 'b>, u64)> { + fn create_lfn_entries(&self, name: &str, short_name: &[u8]) -> io::Result<(DirRawStream<'a, 'b>, u64)> { // get short name checksum let lfn_chsum = lfn_checksum(&short_name); // convert long name to UTF-16 @@ -351,7 +351,7 @@ impl <'a, 'b> Dir<'a, 'b> { Ok((stream, start_pos)) } #[cfg(not(feature = "alloc"))] - fn create_lfn_entries(&mut self, _name: &str, _short_name: &[u8]) -> io::Result<(DirRawStream<'a, 'b>, u64)> { + fn create_lfn_entries(&self, _name: &str, _short_name: &[u8]) -> io::Result<(DirRawStream<'a, 'b>, u64)> { let mut stream = self.find_free_entries(1)?; let start_pos = stream.seek(io::SeekFrom::Current(0))?; Ok((stream, start_pos)) @@ -366,7 +366,7 @@ impl <'a, 'b> Dir<'a, 'b> { raw_entry } - fn write_entry(&mut self, name: &str, raw_entry: DirFileEntryData) -> io::Result> { + fn write_entry(&self, name: &str, raw_entry: DirFileEntryData) -> io::Result> { trace!("write_entry {}", name); // check if name doesn't contain unsupported characters validate_long_name(name)?; diff --git a/src/dir_entry.rs b/src/dir_entry.rs index 13866d4..f379792 100644 --- a/src/dir_entry.rs +++ b/src/dir_entry.rs @@ -350,10 +350,10 @@ pub(crate) enum DirEntryData { } impl DirEntryData { - pub(crate) fn serialize(&mut self, wrt: &mut Write) -> io::Result<()> { + pub(crate) fn serialize(&self, wrt: &mut Write) -> io::Result<()> { match self { - &mut DirEntryData::File(ref mut file) => file.serialize(wrt), - &mut DirEntryData::Lfn(ref mut lfn) => lfn.serialize(wrt), + &DirEntryData::File(ref file) => file.serialize(wrt), + &DirEntryData::Lfn(ref lfn) => lfn.serialize(wrt), } } diff --git a/tests/read.rs b/tests/read.rs index 0feb940..e770f9c 100644 --- a/tests/read.rs +++ b/tests/read.rs @@ -49,7 +49,7 @@ fn test_root_dir_fat32() { } fn test_read_seek_short_file(fs: FileSystem) { - let mut root_dir = fs.root_dir(); + let root_dir = fs.root_dir(); let mut short_file = root_dir.open_file("short.txt").unwrap(); let mut buf = Vec::new(); short_file.read_to_end(&mut buf).unwrap(); @@ -81,7 +81,7 @@ fn test_read_seek_short_file_fat32() { } fn test_read_long_file(fs: FileSystem) { - let mut root_dir = fs.root_dir(); + let root_dir = fs.root_dir(); let mut long_file = root_dir.open_file("long.txt").unwrap(); let mut buf = Vec::new(); long_file.read_to_end(&mut buf).unwrap(); @@ -110,7 +110,7 @@ fn test_read_long_file_fat32() { } fn test_get_dir_by_path(fs: FileSystem) { - let mut root_dir = fs.root_dir(); + let root_dir = fs.root_dir(); let dir = root_dir.open_dir("very/long/path/").unwrap(); let names = dir.iter().map(|r| r.unwrap().file_name()).collect::>(); assert_eq!(names, [".", "..", "test.txt"]); @@ -143,7 +143,7 @@ fn test_get_dir_by_path_fat32() { } fn test_get_file_by_path(fs: FileSystem) { - let mut root_dir = fs.root_dir(); + let root_dir = fs.root_dir(); let mut file = root_dir.open_file("very/long/path/test.txt").unwrap(); let mut buf = Vec::new(); file.read_to_end(&mut buf).unwrap(); diff --git a/tests/write.rs b/tests/write.rs index 8fe58fe..4817523 100644 --- a/tests/write.rs +++ b/tests/write.rs @@ -33,7 +33,7 @@ fn call_with_fs(f: &Fn(FileSystem) -> (), filename: &str, test_seq: u32) { } fn test_write_short_file(fs: FileSystem) { - let mut root_dir = fs.root_dir(); + let root_dir = fs.root_dir(); let mut file = root_dir.open_file("short.txt").expect("open file"); file.truncate().unwrap(); file.write_all(&TEST_STR.as_bytes()).unwrap(); @@ -59,7 +59,7 @@ fn test_write_file_fat32() { } fn test_write_long_file(fs: FileSystem) { - let mut root_dir = fs.root_dir(); + let root_dir = fs.root_dir(); let mut file = root_dir.open_file("long.txt").expect("open file"); file.truncate().unwrap(); let test_str = TEST_STR.repeat(100); @@ -92,7 +92,7 @@ fn test_write_long_file_fat32() { } fn test_remove(fs: FileSystem) { - let mut root_dir = fs.root_dir(); + let root_dir = fs.root_dir(); assert!(root_dir.remove("very/long/path").is_err()); let dir = root_dir.open_dir("very/long/path").unwrap(); let mut names = dir.iter().map(|r| r.unwrap().file_name()).collect::>(); @@ -125,8 +125,8 @@ fn test_remove_fat32() { } fn test_create_file(fs: FileSystem) { - let mut root_dir = fs.root_dir(); - let mut dir = root_dir.open_dir("very/long/path").unwrap(); + let root_dir = fs.root_dir(); + let dir = root_dir.open_dir("very/long/path").unwrap(); let mut names = dir.iter().map(|r| r.unwrap().file_name()).collect::>(); assert_eq!(names, [".", "..", "test.txt"]); { @@ -174,7 +174,7 @@ fn test_create_file_fat32() { } fn test_create_dir(fs: FileSystem) { - let mut root_dir = fs.root_dir(); + let root_dir = fs.root_dir(); let parent_dir = root_dir.open_dir("very/long/path").unwrap(); let mut names = parent_dir.iter().map(|r| r.unwrap().file_name()).collect::>(); assert_eq!(names, [".", "..", "test.txt"]); @@ -222,16 +222,15 @@ fn test_create_dir_fat32() { } fn test_rename_file(fs: FileSystem) { - let mut root_dir = fs.root_dir(); - let mut parent_dir = root_dir.open_dir("very/long/path").unwrap(); + let root_dir = fs.root_dir(); + let parent_dir = root_dir.open_dir("very/long/path").unwrap(); let entries = parent_dir.iter().map(|r| r.unwrap()).collect::>(); let names = entries.iter().map(|r| r.file_name()).collect::>(); assert_eq!(names, [".", "..", "test.txt"]); assert_eq!(entries[2].len(), 14); let stats = fs.stats().unwrap(); - let mut parent_dir_cloned = parent_dir.clone(); - parent_dir.rename("test.txt", &mut parent_dir_cloned, "new-long-name.txt").unwrap(); + parent_dir.rename("test.txt", &parent_dir, "new-long-name.txt").unwrap(); let entries = parent_dir.iter().map(|r| r.unwrap()).collect::>(); let names = entries.iter().map(|r| r.file_name()).collect::>(); assert_eq!(names, [".", "..", "new-long-name.txt"]); @@ -241,7 +240,7 @@ fn test_rename_file(fs: FileSystem) { file.read_to_end(&mut buf).unwrap(); assert_eq!(str::from_utf8(&buf).unwrap(), TEST_STR2); - parent_dir.rename("new-long-name.txt", &mut root_dir, "moved-file.txt").unwrap(); + parent_dir.rename("new-long-name.txt", &root_dir, "moved-file.txt").unwrap(); let entries = root_dir.iter().map(|r| r.unwrap()).collect::>(); let names = entries.iter().map(|r| r.file_name()).collect::>(); assert_eq!(names, ["long.txt", "short.txt", "very", "very-long-dir-name", "moved-file.txt"]);