diff --git a/src/buffer/mod.rs b/src/buffer/mod.rs index e3be829..a4bd6dd 100644 --- a/src/buffer/mod.rs +++ b/src/buffer/mod.rs @@ -6,17 +6,22 @@ use alloc::Vec; use alloc::boxed::Box; use alloc::borrow::{Cow, ToOwned}; -pub mod length; +use error::Infallible; +pub mod length; use self::length::Length; pub trait Buffer where [T]: ToOwned, { + type Error; + fn len(&self) -> Length; - // TODO: return Result - fn commit(&mut self, slice: Option>); + fn commit( + &mut self, + slice: Option>, + ) -> Result<(), Self::Error>; unsafe fn slice_unchecked<'a>( &'a self, range: Range, @@ -214,11 +219,13 @@ macro_rules! impl_slice { T: Clone, [T]: ToOwned, { + type Error = Infallible; + fn len(&self) -> Length { Length::Bounded(>::as_ref(self).len()) } - fn commit(&mut self, slice: Option>) { + fn commit(&mut self, slice: Option>) -> Result<(), Infallible> { slice.map(|slice| { let index = slice.at_index(); let end = index + slice.as_ref().len(); @@ -228,6 +235,7 @@ macro_rules! impl_slice { &mut >::as_mut(self)[index..end]; dst.clone_from_slice(slice.as_ref()); }); + Ok(()) } unsafe fn slice_unchecked<'a>( @@ -250,14 +258,14 @@ macro_rules! impl_slice { }; } -//impl_slice!('a, &'a mut [T]); +//impl_slice!(&'a mut [T], 'a); impl_slice!(Vec); impl_slice!(Box<[T]>); #[cfg(any(test, not(feature = "no_std")))] mod file { use std::ops::Range; - use std::io::{Read, Seek, SeekFrom, Write}; + use std::io::{self, Read, Seek, SeekFrom, Write}; use std::fs::File; use std::cell::RefCell; @@ -265,6 +273,8 @@ mod file { use super::length::Length; impl Buffer for RefCell { + type Error = io::Error; + fn len(&self) -> Length { Length::Bounded( self.borrow() @@ -274,15 +284,21 @@ mod file { ) } - fn commit(&mut self, slice: Option>) { - slice.map(|slice| { - let index = slice.at_index(); - let end = index + slice.as_ref().len(); - let mut refmut = self.borrow_mut(); - let _ = refmut - .seek(SeekFrom::Start(index as u64)) - .and_then(|_| refmut.write(&slice.as_ref()[index..end])); - }); + fn commit( + &mut self, + slice: Option>, + ) -> Result<(), Self::Error> { + slice + .map(|slice| { + let index = slice.at_index(); + let end = index + slice.as_ref().len(); + let mut refmut = self.borrow_mut(); + refmut + .seek(SeekFrom::Start(index as u64)) + .and_then(|_| refmut.write(&slice.as_ref()[index..end])) + .map(|_| ()) + }) + .unwrap_or(Ok(())) } unsafe fn slice_unchecked<'a>( @@ -329,7 +345,7 @@ mod tests { slice.iter_mut().for_each(|x| *x = 1); slice.commit() }; - buffer.commit(commit); + assert!(buffer.commit(commit).is_ok()); for (i, &x) in buffer.iter().enumerate() { if i < 256 || i >= 512 { diff --git a/src/fs.rs b/src/fs.rs index 2d80417..bad1c3f 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -8,7 +8,10 @@ pub struct Ext2> { superblock: Option<(Superblock, usize)>, } -impl> Ext2 { +impl> Ext2 +where + Error: From, +{ pub fn new(buffer: B) -> Ext2 { Ext2 { buffer, diff --git a/src/lib.rs b/src/lib.rs index 1ce4792..3e10f43 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,13 @@ #![feature(alloc)] #![feature(specialization)] #![feature(swap_with_slice)] -#![cfg_attr(not(test), no_std)] +#![feature(macro_lifetime_matcher)] +#![cfg_attr(all(not(test), feature = "no_std"), no_std)] extern crate alloc; #[macro_use] extern crate bitflags; -#[cfg(test)] +#[cfg(any(test, not(feature = "no_std")))] extern crate core; pub mod error; diff --git a/src/sys/superblock.rs b/src/sys/superblock.rs index b179d6f..d58d689 100644 --- a/src/sys/superblock.rs +++ b/src/sys/superblock.rs @@ -145,9 +145,12 @@ pub struct Superblock { } impl Superblock { - pub fn find<'a>( - haystack: &'a Buffer, - ) -> Result<(Superblock, usize), Error> { + pub fn find<'a, E>( + haystack: &'a Buffer, + ) -> Result<(Superblock, usize), Error> + where + Error: From, + { let offset = 1024; let end = offset + mem::size_of::(); if haystack.len() < end {