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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
#![deny(warnings, missing_docs)] // #![cfg_attr(test, feature(plugin))] // #![cfg_attr(test, plugin(clippy))] //! Abstract interface to implement `random-access-storage` instances. //! //! ## Why? //! This module forms a shared interface for reading and writing bytes to //! different backends. By having a shared interface, it means implementations //! can easily be swapped, depending on the environment. //! //! ## Usage //! ```rust,ignore //! extern crate random_access_storage; //! use random_access_storage::{Error, Sync, SyncMethods}; //! //! struct S; //! impl SyncMethods for S { //! fn open(&self) -> Result<(), Error> { //! // ... //! } //! fn write(&self, offset: u64, data: Vec<u8>) -> Result<(), Error> { //! // ... //! } //! fn read(&self, offset: u64, length: u64) -> Result<Vec<u8>, Error> { //! // ... //! } //! fn del(&self, offset: u64, length: u64) -> Result<(), Error> { //! // ... //! } //! } //! //! let file = Sync::new(SyncMethods); //! file.write(0, b"hello")?; //! file.write(0, b" world")?; //! let text = file.read(0, 11,)?; //! assert!(text, b"hello world"); //! ``` pub extern crate failure; pub use failure::Error; /// Methods that need to be implemented for the `Sync` struct. pub trait SyncMethods { /// Open the backend. fn open(&self) -> Result<(), Error>; /// Write bytes at an offset to the backend. fn write(&self, offset: u64, data: Vec<u8>) -> Result<(), Error>; /// Read a sequence of bytes at an offset from the backend. fn read(&self, offset: u64, length: u64) -> Result<Vec<u8>, Error>; /// Delete a sequence of bytes at an offset from the backend. fn del(&self, offset: u64, length: u64) -> Result<(), Error>; } /// A synchronous implementation of `random_access_storage`. #[derive(Debug)] pub struct Sync<T> { handler: T, is_open: bool, } impl<T> Sync<T> where T: SyncMethods, { /// Create a new `Sync` instance. pub fn new(handler: T) -> Sync<T> { Sync { handler: handler, is_open: false, } } /// Write bytes at an offset. Calls `SyncMethods::write` under the hood. pub fn write(&mut self, offset: u64, data: Vec<u8>) -> Result<(), Error> { if !self.is_open { T::open(&self.handler)?; self.is_open = true; } T::write(&self.handler, offset, data) } /// Write bytes from an offset. Calls `SyncMethods::read` under the hood. pub fn read(&mut self, offset: u64, length: u64) -> Result<Vec<u8>, Error> { if !self.is_open { T::open(&self.handler)?; self.is_open = true; } T::read(&self.handler, offset, length) } /// Delete bytes from an offset. Calls `SyncMethods::del` under the hood. pub fn del(&mut self, offset: u64, length: u64) -> Result<(), Error> { if !self.is_open { T::open(&self.handler)?; self.is_open = true; } T::del(&self.handler, offset, length) } }