add Result return type to fn commit

This commit is contained in:
Szymon Walter 2018-03-19 13:30:42 +01:00
parent 110d2ff415
commit 55b23f4974
4 changed files with 45 additions and 22 deletions

View file

@ -6,17 +6,22 @@ use alloc::Vec;
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::borrow::{Cow, ToOwned}; use alloc::borrow::{Cow, ToOwned};
pub mod length; use error::Infallible;
pub mod length;
use self::length::Length; use self::length::Length;
pub trait Buffer<T> pub trait Buffer<T>
where where
[T]: ToOwned, [T]: ToOwned,
{ {
type Error;
fn len(&self) -> Length; fn len(&self) -> Length;
// TODO: return Result fn commit(
fn commit(&mut self, slice: Option<BufferCommit<T>>); &mut self,
slice: Option<BufferCommit<T>>,
) -> Result<(), Self::Error>;
unsafe fn slice_unchecked<'a>( unsafe fn slice_unchecked<'a>(
&'a self, &'a self,
range: Range<usize>, range: Range<usize>,
@ -214,11 +219,13 @@ macro_rules! impl_slice {
T: Clone, T: Clone,
[T]: ToOwned, [T]: ToOwned,
{ {
type Error = Infallible;
fn len(&self) -> Length { fn len(&self) -> Length {
Length::Bounded(<Self as AsRef<[T]>>::as_ref(self).len()) Length::Bounded(<Self as AsRef<[T]>>::as_ref(self).len())
} }
fn commit(&mut self, slice: Option<BufferCommit<T>>) { fn commit(&mut self, slice: Option<BufferCommit<T>>) -> Result<(), Infallible> {
slice.map(|slice| { slice.map(|slice| {
let index = slice.at_index(); let index = slice.at_index();
let end = index + slice.as_ref().len(); let end = index + slice.as_ref().len();
@ -228,6 +235,7 @@ macro_rules! impl_slice {
&mut <Self as AsMut<[T]>>::as_mut(self)[index..end]; &mut <Self as AsMut<[T]>>::as_mut(self)[index..end];
dst.clone_from_slice(slice.as_ref()); dst.clone_from_slice(slice.as_ref());
}); });
Ok(())
} }
unsafe fn slice_unchecked<'a>( 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<T>); impl_slice!(Vec<T>);
impl_slice!(Box<[T]>); impl_slice!(Box<[T]>);
#[cfg(any(test, not(feature = "no_std")))] #[cfg(any(test, not(feature = "no_std")))]
mod file { mod file {
use std::ops::Range; 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::fs::File;
use std::cell::RefCell; use std::cell::RefCell;
@ -265,6 +273,8 @@ mod file {
use super::length::Length; use super::length::Length;
impl Buffer<u8> for RefCell<File> { impl Buffer<u8> for RefCell<File> {
type Error = io::Error;
fn len(&self) -> Length { fn len(&self) -> Length {
Length::Bounded( Length::Bounded(
self.borrow() self.borrow()
@ -274,15 +284,21 @@ mod file {
) )
} }
fn commit(&mut self, slice: Option<BufferCommit<u8>>) { fn commit(
slice.map(|slice| { &mut self,
slice: Option<BufferCommit<u8>>,
) -> Result<(), Self::Error> {
slice
.map(|slice| {
let index = slice.at_index(); let index = slice.at_index();
let end = index + slice.as_ref().len(); let end = index + slice.as_ref().len();
let mut refmut = self.borrow_mut(); let mut refmut = self.borrow_mut();
let _ = refmut refmut
.seek(SeekFrom::Start(index as u64)) .seek(SeekFrom::Start(index as u64))
.and_then(|_| refmut.write(&slice.as_ref()[index..end])); .and_then(|_| refmut.write(&slice.as_ref()[index..end]))
}); .map(|_| ())
})
.unwrap_or(Ok(()))
} }
unsafe fn slice_unchecked<'a>( unsafe fn slice_unchecked<'a>(
@ -329,7 +345,7 @@ mod tests {
slice.iter_mut().for_each(|x| *x = 1); slice.iter_mut().for_each(|x| *x = 1);
slice.commit() slice.commit()
}; };
buffer.commit(commit); assert!(buffer.commit(commit).is_ok());
for (i, &x) in buffer.iter().enumerate() { for (i, &x) in buffer.iter().enumerate() {
if i < 256 || i >= 512 { if i < 256 || i >= 512 {

View file

@ -8,7 +8,10 @@ pub struct Ext2<B: Buffer<u8>> {
superblock: Option<(Superblock, usize)>, superblock: Option<(Superblock, usize)>,
} }
impl<B: Buffer<u8>> Ext2<B> { impl<B: Buffer<u8>> Ext2<B>
where
Error: From<B::Error>,
{
pub fn new(buffer: B) -> Ext2<B> { pub fn new(buffer: B) -> Ext2<B> {
Ext2 { Ext2 {
buffer, buffer,

View file

@ -1,12 +1,13 @@
#![feature(alloc)] #![feature(alloc)]
#![feature(specialization)] #![feature(specialization)]
#![feature(swap_with_slice)] #![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; extern crate alloc;
#[macro_use] #[macro_use]
extern crate bitflags; extern crate bitflags;
#[cfg(test)] #[cfg(any(test, not(feature = "no_std")))]
extern crate core; extern crate core;
pub mod error; pub mod error;

View file

@ -145,9 +145,12 @@ pub struct Superblock {
} }
impl Superblock { impl Superblock {
pub fn find<'a>( pub fn find<'a, E>(
haystack: &'a Buffer<u8>, haystack: &'a Buffer<u8, Error = E>,
) -> Result<(Superblock, usize), Error> { ) -> Result<(Superblock, usize), Error>
where
Error: From<E>,
{
let offset = 1024; let offset = 1024;
let end = offset + mem::size_of::<Superblock>(); let end = offset + mem::size_of::<Superblock>();
if haystack.len() < end { if haystack.len() < end {