Struct LazyTransducer

Source
pub struct LazyTransducer<'a, Input, Output>
where Input: 'a + Copy, Output: 'a,
{ /* private fields */ }
Expand description

A lazy transducer transforms n elements from a source type into an output type.

The transformer is called the transducer, which receives the original source input, and an index corresponding to the ith element, and returns the corresponding ith element out of that source.

Importantly, lazy transducers are:

  1. Lazy - it never parses any elements unless you request it to do so
  2. Iterable - one can iterate over every element
  3. Indexable - accessing an element is O(1)
  4. Parallel - one can iterate in parallel over every element

§Basic Example

We need to provide a data source, the number of elements in the data source, and the means of extracting the elements out of the data source (the transducer).

For a simple case, we can consider a backing array of u32s, which we cast to u64s.

extern crate lazy_transducer;
use lazy_transducer::LazyTransducer;

let data = [0xdeadbeefu32, 0xcafed00d];
let lt: LazyTransducer<&[u32], u64> = LazyTransducer::new(&data, 2, |input, idx| input[idx] as u64);

let cafedood = lt.get(1).expect("has 2 elements");
assert_eq!(cafedood, 0xcafed00d);

for (i, elem) in lt.into_iter().enumerate() {
  println!("{}: {}", i, elem);
}

§Advanced Example

This example uses the bincode binary serializer as its transducer.

extern crate lazy_transducer;
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate bincode;
extern crate rayon;

use lazy_transducer::LazyTransducer;
use bincode::{serialize, deserialize, Error};
use rayon::prelude::*;

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Foo {
  x: u64,
  y: f32,
  z: bool,
}

fn run() -> Result<(), Error> {
  let foo1 = Foo { x: 0xcafed00d, y: 0.75, z: false };
  let foo2 = Foo { x: 0xdeadbeef, y: 0.50, z: true };

  // we need to serialize the data, which we do by extending a byte vector with the individually
  // serialized components
  let mut data = serialize(&foo1)?;
  let sizeof_serialized_element = data.len();
  data.extend_from_slice(&serialize(&foo2)?);

  // we construct our transducer by providing the serialized bytes _and_ the size of a serialized
  // element as input; our transducer just reads at the appropriate byte offset, and deserializes!
  let lt: LazyTransducer<_, Result<Foo, Error>> =
    LazyTransducer::new((data.as_slice(), sizeof_serialized_element),
                        2,
                        |(input, size), idx| {
                           deserialize(&input[(idx * size)..])
  });

  let foo2_ = lt.get(1).expect("has 2 elements")?;
  assert_eq!(foo2, foo2_);

  // and now with the help of rayon, we iterate over the items in parallel
  lt.into_par_iter().for_each(|elem| {
    println!("{:?}", elem);
  });
  Ok(())
}

Implementations§

Source§

impl<'a, Input, Output> LazyTransducer<'a, Input, Output>
where Input: 'a + Copy, Output: 'a,

Source

pub fn len(&self) -> usize

How many elements are contained in this lazy transducer

Source

pub fn new( contents: Input, count: usize, transducer: fn(Input, usize) -> Output, ) -> Self

Create a new LazyTransducer with count elements in contents, using transducer to extract them.

§Example
use lazy_transducer::LazyTransducer;
let data = [0xdeadbeefu32, 0xcafed00d];
let lt: LazyTransducer<&[u32], u64> = LazyTransducer::new(&data, 2, |input, idx| input[idx] as u64);
Source

pub fn get(&self, idx: usize) -> Option<Output>

Get an element out of the lazy transducer, returning None if the index is greater than the number of elements in this lazy transducer.

§Example
extern crate lazy_transducer;
use lazy_transducer::LazyTransducer;

let data = [0xdeadbeefu64, 0xcafed00d];
let lt: LazyTransducer<&[u64], &u64> = LazyTransducer::new(&data, 2, |input, idx| &input[idx]);

let cafedood = lt.get(1).expect("has 2 elements");
assert_eq!(*cafedood, 0xcafed00d);

assert!(lt.get(2).is_none());

Trait Implementations§

Source§

impl<'a, Input: Copy, Output> Clone for LazyTransducer<'a, Input, Output>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a, Input, Output> Debug for LazyTransducer<'a, Input, Output>
where Input: 'a + Copy + Debug, Output: 'a + Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a, 'b, Input: Copy, Output> IntoIterator for &'b LazyTransducer<'a, Input, Output>

Source§

type Item = Output

The type of the elements being iterated over.
Source§

type IntoIter = IntoIter<'a, Input, Output>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
Source§

impl<'a, Input: Copy, Output> IntoIterator for LazyTransducer<'a, Input, Output>

Source§

type Item = Output

The type of the elements being iterated over.
Source§

type IntoIter = IntoIter<'a, Input, Output>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
Source§

impl<'a, Input: Sync + Copy + Send, Output: Send + Sync> IntoParallelIterator for LazyTransducer<'a, Input, Output>

Source§

type Iter = IntoParIter<'a, Input, Output>

The parallel iterator type that will be created.
Source§

type Item = Output

The type of item that the parallel iterator will produce.
Source§

fn into_par_iter(self) -> Self::Iter

Converts self into a parallel iterator. Read more

Auto Trait Implementations§

§

impl<'a, Input, Output> Freeze for LazyTransducer<'a, Input, Output>
where Input: Freeze,

§

impl<'a, Input, Output> RefUnwindSafe for LazyTransducer<'a, Input, Output>
where Input: RefUnwindSafe, Output: RefUnwindSafe,

§

impl<'a, Input, Output> Send for LazyTransducer<'a, Input, Output>
where Input: Send, Output: Sync,

§

impl<'a, Input, Output> Sync for LazyTransducer<'a, Input, Output>
where Input: Sync, Output: Sync,

§

impl<'a, Input, Output> Unpin for LazyTransducer<'a, Input, Output>
where Input: Unpin,

§

impl<'a, Input, Output> UnwindSafe for LazyTransducer<'a, Input, Output>
where Input: UnwindSafe, Output: RefUnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.