diff --git a/Cargo.toml b/Cargo.toml index 088ed8c5..0e17a64b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fasten" -version = "0.8.3" +version = "0.8.4" authors = ["Lee Katz "] #license-file = "LICENSE" license = "MIT" diff --git a/docs/fasten/all.html b/docs/fasten/all.html index 88f69990..d35a03c6 100644 --- a/docs/fasten/all.html +++ b/docs/fasten/all.html @@ -1 +1,2 @@ -List of all items in this crate
\ No newline at end of file +List of all items in this crate +
\ No newline at end of file diff --git a/docs/fasten/fn.eexit.html b/docs/fasten/fn.eexit.html index 5d9979a5..9f033a5a 100644 --- a/docs/fasten/fn.eexit.html +++ b/docs/fasten/fn.eexit.html @@ -1,2 +1,3 @@ -eexit in fasten - Rust

Function fasten::eexit

source ·
pub fn eexit()
Expand description

Propagate an error by printing invalid read(s)

+eexit in fasten - Rust +

Function fasten::eexit

source ·
pub fn eexit()
Expand description

Propagate an error by printing invalid read(s)

\ No newline at end of file diff --git a/docs/fasten/fn.fasten_base_options.html b/docs/fasten/fn.fasten_base_options.html index 503b825c..068a48f8 100644 --- a/docs/fasten/fn.fasten_base_options.html +++ b/docs/fasten/fn.fasten_base_options.html @@ -1,2 +1,3 @@ -fasten_base_options in fasten - Rust
pub fn fasten_base_options() -> Options
Expand description

a function that reads an options object and adds fasten default options.

+fasten_base_options in fasten - Rust +
pub fn fasten_base_options() -> Options
Expand description

a function that reads an options object and adds fasten default options.

\ No newline at end of file diff --git a/docs/fasten/fn.fasten_base_options_matches.html b/docs/fasten/fn.fasten_base_options_matches.html index 12da3bdf..f7db0c94 100644 --- a/docs/fasten/fn.fasten_base_options_matches.html +++ b/docs/fasten/fn.fasten_base_options_matches.html @@ -1,4 +1,5 @@ -fasten_base_options_matches in fasten - Rust
pub fn fasten_base_options_matches(brief: &str, opts: Options) -> Matches
Expand description

a function that processes the options on the command line +fasten_base_options_matches in fasten - Rust

+
pub fn fasten_base_options_matches(brief: &str, opts: Options) -> Matches
Expand description

a function that processes the options on the command line The brief is a str that describes the program without using the program name, e.g., “counts kmers” for fasten_kmer. This function also takes care of –version. diff --git a/docs/fasten/fn.logmsg.html b/docs/fasten/fn.logmsg.html index b8f1394f..492c4232 100644 --- a/docs/fasten/fn.logmsg.html +++ b/docs/fasten/fn.logmsg.html @@ -1,2 +1,3 @@ -logmsg in fasten - Rust

Function fasten::logmsg

source ·
pub fn logmsg<S: AsRef<str>>(stringlike: S)
Expand description

Print a formatted message to stderr

+logmsg in fasten - Rust +

Function fasten::logmsg

source ·
pub fn logmsg<S: AsRef<str>>(stringlike: S)
Expand description

Print a formatted message to stderr

\ No newline at end of file diff --git a/docs/fasten/fn.reverse_complement.html b/docs/fasten/fn.reverse_complement.html new file mode 100644 index 00000000..80ab7086 --- /dev/null +++ b/docs/fasten/fn.reverse_complement.html @@ -0,0 +1,5 @@ +reverse_complement in fasten - Rust +

Function fasten::reverse_complement

source ·
pub fn reverse_complement(dna: &str) -> String
Expand description

Reverse complement a DNA sequence. +Take into account lowercase vs uppercase. +Ambiguity codes are also handled.

+
\ No newline at end of file diff --git a/docs/fasten/index.html b/docs/fasten/index.html index 70d259f2..cb6c903c 100644 --- a/docs/fasten/index.html +++ b/docs/fasten/index.html @@ -1,11 +1,13 @@ -fasten - Rust

Crate fasten

source ·
Expand description

Perform random operations on fastq files, using unix streaming. +fasten - Rust

+

Crate fasten

source ·
Expand description

Perform random operations on fastq files, using unix streaming. Secure your analysis with Fasten!

-

Synopsis

read metrics

 
+

§Synopsis

§read metrics

 
 $ cat testdata/R1.fastq testdata/R2.fastq | \
     fasten_shuffle | fasten_metrics | column -t
 totalLength  numReads  avgReadLength  avgQual
 800          8         100            19.53875
-

read cleaning

$ cat testdata/R1.fastq testdata/R2.fastq | \
+

§read cleaning

$ cat testdata/R1.fastq testdata/R2.fastq | \
     fasten_shuffle | \
     fasten_clean --paired-end --min-length 2 | \
     gzip -c > cleaned.shuffled.fastq.gz
@@ -15,12 +17,12 @@ 

Synopsis

NOTE: No reads were actually filtered with cleaning, with –min-length=2

-

Kmer counting

$ cat testdata/R1.fastq | \
+

§Kmer counting

$ cat testdata/R1.fastq | \
   fasten_kmer -k 21 > 21mers.tsv
-

Read sampling

$ cat testdata/R1.fastq testdata/R2.fastq | \
+

§Read sampling

$ cat testdata/R1.fastq testdata/R2.fastq | \
     fasten_shuffle | \
     fasten_sample --paired-end --frequency 0.1 > 10percent.fastq
-

Advanced

Set of downsampled reads

+

§Advanced

§Set of downsampled reads

Create a set of downsampled reads for a titration experiment and clean them

for frequency in 0.1 0.2 0.3 0.4 0.5; do
@@ -29,16 +31,18 @@ 

Kmer counting

Validate a whole directory of fastq reads

\ls *_1.fastq.gz | xargs -n 1 -P 4 bash -c '
+

§Validate a whole directory of fastq reads

\ls *_1.fastq.gz | xargs -n 1 -P 4 bash -c '
   echo -n "." >&2 # progress bar
   R1=$0
   R2=${0/_1.fastq.gz/_2.fastq.gz}
   zcat $R1 $R2 | fasten_shuffle | fasten_validate --paired-end
 '
-

Modules

  • input/output methods

Macros

  • Rewrite print!() so that it doesn’t panic on broken -pipe.

Functions

Modules§

  • input/output methods

Macros§

  • Rewrite print!() so that it doesn’t panic on broken +pipe.

Functions§

  • Propagate an error by printing invalid read(s)
  • a function that reads an options object and adds fasten default options.
  • a function that processes the options on the command line The brief is a str that describes the program without using the program name, e.g., “counts kmers” for fasten_kmer. This function also takes care of –version. If –help is invoked, then the program name, the brief, and the usage() -are all printed to stdout and then the program exits with 0.
  • Print a formatted message to stderr
\ No newline at end of file +are all printed to stdout and then the program exits with 0.
  • Print a formatted message to stderr
  • Reverse complement a DNA sequence. +Take into account lowercase vs uppercase. +Ambiguity codes are also handled.
  • \ No newline at end of file diff --git a/docs/fasten/io/fastq/index.html b/docs/fasten/io/fastq/index.html index ffb57607..12e15f3b 100644 --- a/docs/fasten/io/fastq/index.html +++ b/docs/fasten/io/fastq/index.html @@ -1 +1,2 @@ -fasten::io::fastq - Rust

    Module fasten::io::fastq

    source ·

    Structs

    \ No newline at end of file +fasten::io::fastq - Rust +

    Module fasten::io::fastq

    source ·

    Structs§

    \ No newline at end of file diff --git a/docs/fasten/io/fastq/struct.FastqReader.html b/docs/fasten/io/fastq/struct.FastqReader.html index 764c8bec..51fad49e 100644 --- a/docs/fasten/io/fastq/struct.FastqReader.html +++ b/docs/fasten/io/fastq/struct.FastqReader.html @@ -1,209 +1,206 @@ -FastqReader in fasten::io::fastq - Rust

    Struct fasten::io::fastq::FastqReader

    source ·
    pub struct FastqReader<R: Read> { /* private fields */ }
    Expand description

    A FastQ reader

    -

    Implementations§

    source§

    impl<R: Read> FastqReader<R>

    source

    pub fn new(reader: R) -> FastqReader<R>

    source

    pub fn new_careful(reader: R) -> FastqReader<R>

    Trait Implementations§

    source§

    impl<R: Read> Iterator for FastqReader<R>

    source§

    fn next(&mut self) -> Option<Seq>

    There are two flavors of next: either read +FastqReader in fasten::io::fastq - Rust

    +

    Struct fasten::io::fastq::FastqReader

    source ·
    pub struct FastqReader<R: Read> { /* private fields */ }
    Expand description

    A FastQ reader

    +

    Implementations§

    source§

    impl<R: Read> FastqReader<R>

    source

    pub fn new(reader: R) -> FastqReader<R>

    source

    pub fn new_careful(reader: R) -> FastqReader<R>

    Trait Implementations§

    source§

    impl<R: Read> Iterator for FastqReader<R>

    source§

    fn next(&mut self) -> Option<Seq>

    There are two flavors of next: either read quickly or read carefully, depending on the ‘quickly’ bool.

    -
    §

    type Item = Seq

    The type of the elements being iterated over.
    source§

    fn next_chunk<const N: usize>( +

    §

    type Item = Seq

    The type of the elements being iterated over.
    source§

    fn next_chunk<const N: usize>( &mut self -) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where - Self: Sized,

    🔬This is a nightly-only experimental API. (iter_next_chunk)
    Advances the iterator and returns an array containing the next N values. Read more
    1.0.0 · source§

    fn size_hint(&self) -> (usize, Option<usize>)

    Returns the bounds on the remaining length of the iterator. Read more
    1.0.0 · source§

    fn count(self) -> usizewhere - Self: Sized,

    Consumes the iterator, counting the number of iterations and returning it. Read more
    1.0.0 · source§

    fn last(self) -> Option<Self::Item>where - Self: Sized,

    Consumes the iterator, returning the last element. Read more
    source§

    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

    🔬This is a nightly-only experimental API. (iter_advance_by)
    Advances the iterator by n elements. Read more
    1.0.0 · source§

    fn nth(&mut self, n: usize) -> Option<Self::Item>

    Returns the nth element of the iterator. Read more
    1.28.0 · source§

    fn step_by(self, step: usize) -> StepBy<Self>where - Self: Sized,

    Creates an iterator starting at the same point, but stepping by -the given amount at each iteration. Read more
    1.0.0 · source§

    fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where - Self: Sized, - U: IntoIterator<Item = Self::Item>,

    Takes two iterators and creates a new iterator over both in sequence. Read more
    1.0.0 · source§

    fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where - Self: Sized, - U: IntoIterator,

    ‘Zips up’ two iterators into a single iterator of pairs. Read more
    source§

    fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where - Self: Sized, - G: FnMut() -> Self::Item,

    🔬This is a nightly-only experimental API. (iter_intersperse)
    Creates a new iterator which places an item generated by separator -between adjacent items of the original iterator. Read more
    1.0.0 · source§

    fn map<B, F>(self, f: F) -> Map<Self, F>where - Self: Sized, - F: FnMut(Self::Item) -> B,

    Takes a closure and creates an iterator which calls that closure on each -element. Read more
    1.21.0 · source§

    fn for_each<F>(self, f: F)where - Self: Sized, - F: FnMut(Self::Item),

    Calls a closure on each element of an iterator. Read more
    1.0.0 · source§

    fn filter<P>(self, predicate: P) -> Filter<Self, P>where - Self: Sized, - P: FnMut(&Self::Item) -> bool,

    Creates an iterator which uses a closure to determine if an element -should be yielded. Read more
    1.0.0 · source§

    fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where - Self: Sized, - F: FnMut(Self::Item) -> Option<B>,

    Creates an iterator that both filters and maps. Read more
    1.0.0 · source§

    fn enumerate(self) -> Enumerate<Self>where - Self: Sized,

    Creates an iterator which gives the current iteration count as well as -the next value. Read more
    1.0.0 · source§

    fn peekable(self) -> Peekable<Self>where - Self: Sized,

    Creates an iterator which can use the peek and peek_mut methods +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
    where + Self: Sized,
    🔬This is a nightly-only experimental API. (iter_next_chunk)
    Advances the iterator and returns an array containing the next N values. Read more
    1.0.0 · source§

    fn size_hint(&self) -> (usize, Option<usize>)

    Returns the bounds on the remaining length of the iterator. Read more
    1.0.0 · source§

    fn count(self) -> usize
    where + Self: Sized,

    Consumes the iterator, counting the number of iterations and returning it. Read more
    1.0.0 · source§

    fn last(self) -> Option<Self::Item>
    where + Self: Sized,

    Consumes the iterator, returning the last element. Read more
    source§

    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

    🔬This is a nightly-only experimental API. (iter_advance_by)
    Advances the iterator by n elements. Read more
    1.0.0 · source§

    fn nth(&mut self, n: usize) -> Option<Self::Item>

    Returns the nth element of the iterator. Read more
    1.28.0 · source§

    fn step_by(self, step: usize) -> StepBy<Self>
    where + Self: Sized,

    Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
    1.0.0 · source§

    fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
    where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

    Takes two iterators and creates a new iterator over both in sequence. Read more
    1.0.0 · source§

    fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>
    where + Self: Sized, + U: IntoIterator,

    ‘Zips up’ two iterators into a single iterator of pairs. Read more
    source§

    fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
    where + Self: Sized, + G: FnMut() -> Self::Item,

    🔬This is a nightly-only experimental API. (iter_intersperse)
    Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
    1.0.0 · source§

    fn map<B, F>(self, f: F) -> Map<Self, F>
    where + Self: Sized, + F: FnMut(Self::Item) -> B,

    Takes a closure and creates an iterator which calls that closure on each +element. Read more
    1.21.0 · source§

    fn for_each<F>(self, f: F)
    where + Self: Sized, + F: FnMut(Self::Item),

    Calls a closure on each element of an iterator. Read more
    1.0.0 · source§

    fn filter<P>(self, predicate: P) -> Filter<Self, P>
    where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

    Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
    1.0.0 · source§

    fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
    where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

    Creates an iterator that both filters and maps. Read more
    1.0.0 · source§

    fn enumerate(self) -> Enumerate<Self>
    where + Self: Sized,

    Creates an iterator which gives the current iteration count as well as +the next value. Read more
    1.0.0 · source§

    fn peekable(self) -> Peekable<Self>
    where + Self: Sized,

    Creates an iterator which can use the peek and peek_mut methods to look at the next element of the iterator without consuming it. See -their documentation for more information. Read more
    1.0.0 · source§

    fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where - Self: Sized, - P: FnMut(&Self::Item) -> bool,

    Creates an iterator that skips elements based on a predicate. Read more
    1.0.0 · source§

    fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where - Self: Sized, - P: FnMut(&Self::Item) -> bool,

    Creates an iterator that yields elements based on a predicate. Read more
    1.57.0 · source§

    fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where - Self: Sized, - P: FnMut(Self::Item) -> Option<B>,

    Creates an iterator that both yields elements based on a predicate and maps. Read more
    1.0.0 · source§

    fn skip(self, n: usize) -> Skip<Self>where - Self: Sized,

    Creates an iterator that skips the first n elements. Read more
    1.0.0 · source§

    fn take(self, n: usize) -> Take<Self>where - Self: Sized,

    Creates an iterator that yields the first n elements, or fewer -if the underlying iterator ends sooner. Read more
    1.0.0 · source§

    fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where - Self: Sized, - F: FnMut(&mut St, Self::Item) -> Option<B>,

    An iterator adapter which, like fold, holds internal state, but -unlike fold, produces a new iterator. Read more
    1.0.0 · source§

    fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where - Self: Sized, - U: IntoIterator, - F: FnMut(Self::Item) -> U,

    Creates an iterator that works like map, but flattens nested structure. Read more
    source§

    fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where - Self: Sized, - F: FnMut(&[Self::Item; N]) -> R,

    🔬This is a nightly-only experimental API. (iter_map_windows)
    Calls the given function f for each contiguous window of size N over -self and returns an iterator over the outputs of f. Like slice::windows(), -the windows during mapping overlap as well. Read more
    1.0.0 · source§

    fn fuse(self) -> Fuse<Self>where - Self: Sized,

    Creates an iterator which ends after the first None. Read more
    1.0.0 · source§

    fn inspect<F>(self, f: F) -> Inspect<Self, F>where - Self: Sized, - F: FnMut(&Self::Item),

    Does something with each element of an iterator, passing the value on. Read more
    1.0.0 · source§

    fn by_ref(&mut self) -> &mut Selfwhere - Self: Sized,

    Borrows an iterator, rather than consuming it. Read more
    1.0.0 · source§

    fn collect<B>(self) -> Bwhere - B: FromIterator<Self::Item>, - Self: Sized,

    Transforms an iterator into a collection. Read more
    source§

    fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere - E: Extend<Self::Item>, - Self: Sized,

    🔬This is a nightly-only experimental API. (iter_collect_into)
    Collects all the items from an iterator into a collection. Read more
    1.0.0 · source§

    fn partition<B, F>(self, f: F) -> (B, B)where - Self: Sized, - B: Default + Extend<Self::Item>, - F: FnMut(&Self::Item) -> bool,

    Consumes an iterator, creating two collections from it. Read more
    source§

    fn is_partitioned<P>(self, predicate: P) -> boolwhere - Self: Sized, - P: FnMut(Self::Item) -> bool,

    🔬This is a nightly-only experimental API. (iter_is_partitioned)
    Checks if the elements of this iterator are partitioned according to the given predicate, -such that all those that return true precede all those that return false. Read more
    1.27.0 · source§

    fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere - Self: Sized, - F: FnMut(B, Self::Item) -> R, - R: Try<Output = B>,

    An iterator method that applies a function as long as it returns -successfully, producing a single, final value. Read more
    1.27.0 · source§

    fn try_for_each<F, R>(&mut self, f: F) -> Rwhere - Self: Sized, - F: FnMut(Self::Item) -> R, - R: Try<Output = ()>,

    An iterator method that applies a fallible function to each item in the -iterator, stopping at the first error and returning that error. Read more
    1.0.0 · source§

    fn fold<B, F>(self, init: B, f: F) -> Bwhere - Self: Sized, - F: FnMut(B, Self::Item) -> B,

    Folds every element into an accumulator by applying an operation, -returning the final result. Read more
    1.51.0 · source§

    fn reduce<F>(self, f: F) -> Option<Self::Item>where - Self: Sized, - F: FnMut(Self::Item, Self::Item) -> Self::Item,

    Reduces the elements to a single one, by repeatedly applying a reducing -operation. Read more
    source§

    fn try_reduce<F, R>( +their documentation for more information. Read more

    1.0.0 · source§

    fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
    where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

    Creates an iterator that skips elements based on a predicate. Read more
    1.0.0 · source§

    fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
    where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

    Creates an iterator that yields elements based on a predicate. Read more
    1.57.0 · source§

    fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
    where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

    Creates an iterator that both yields elements based on a predicate and maps. Read more
    1.0.0 · source§

    fn skip(self, n: usize) -> Skip<Self>
    where + Self: Sized,

    Creates an iterator that skips the first n elements. Read more
    1.0.0 · source§

    fn take(self, n: usize) -> Take<Self>
    where + Self: Sized,

    Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
    1.0.0 · source§

    fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
    where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

    An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
    1.0.0 · source§

    fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
    where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

    Creates an iterator that works like map, but flattens nested structure. Read more
    source§

    fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
    where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

    🔬This is a nightly-only experimental API. (iter_map_windows)
    Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
    1.0.0 · source§

    fn fuse(self) -> Fuse<Self>
    where + Self: Sized,

    Creates an iterator which ends after the first None. Read more
    1.0.0 · source§

    fn inspect<F>(self, f: F) -> Inspect<Self, F>
    where + Self: Sized, + F: FnMut(&Self::Item),

    Does something with each element of an iterator, passing the value on. Read more
    1.0.0 · source§

    fn by_ref(&mut self) -> &mut Self
    where + Self: Sized,

    Borrows an iterator, rather than consuming it. Read more
    1.0.0 · source§

    fn collect<B>(self) -> B
    where + B: FromIterator<Self::Item>, + Self: Sized,

    Transforms an iterator into a collection. Read more
    source§

    fn collect_into<E>(self, collection: &mut E) -> &mut E
    where + E: Extend<Self::Item>, + Self: Sized,

    🔬This is a nightly-only experimental API. (iter_collect_into)
    Collects all the items from an iterator into a collection. Read more
    1.0.0 · source§

    fn partition<B, F>(self, f: F) -> (B, B)
    where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

    Consumes an iterator, creating two collections from it. Read more
    source§

    fn is_partitioned<P>(self, predicate: P) -> bool
    where + Self: Sized, + P: FnMut(Self::Item) -> bool,

    🔬This is a nightly-only experimental API. (iter_is_partitioned)
    Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
    1.27.0 · source§

    fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
    where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

    An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
    1.27.0 · source§

    fn try_for_each<F, R>(&mut self, f: F) -> R
    where + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

    An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
    1.0.0 · source§

    fn fold<B, F>(self, init: B, f: F) -> B
    where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

    Folds every element into an accumulator by applying an operation, +returning the final result. Read more
    1.51.0 · source§

    fn reduce<F>(self, f: F) -> Option<Self::Item>
    where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

    Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
    source§

    fn try_reduce<F, R>( &mut self, f: F -) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere - Self: Sized, - F: FnMut(Self::Item, Self::Item) -> R, - R: Try<Output = Self::Item>, - <R as Try>::Residual: Residual<Option<Self::Item>>,

    🔬This is a nightly-only experimental API. (iterator_try_reduce)
    Reduces the elements to a single one by repeatedly applying a reducing operation. If the -closure returns a failure, the failure is propagated back to the caller immediately. Read more
    1.0.0 · source§

    fn all<F>(&mut self, f: F) -> boolwhere - Self: Sized, - F: FnMut(Self::Item) -> bool,

    Tests if every element of the iterator matches a predicate. Read more
    1.0.0 · source§

    fn any<F>(&mut self, f: F) -> boolwhere - Self: Sized, - F: FnMut(Self::Item) -> bool,

    Tests if any element of the iterator matches a predicate. Read more
    1.0.0 · source§

    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where - Self: Sized, - P: FnMut(&Self::Item) -> bool,

    Searches for an element of an iterator that satisfies a predicate. Read more
    1.30.0 · source§

    fn find_map<B, F>(&mut self, f: F) -> Option<B>where - Self: Sized, - F: FnMut(Self::Item) -> Option<B>,

    Applies function to the elements of iterator and returns -the first non-none result. Read more
    source§

    fn try_find<F, R>( +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
    where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

    🔬This is a nightly-only experimental API. (iterator_try_reduce)
    Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
    1.0.0 · source§

    fn all<F>(&mut self, f: F) -> bool
    where + Self: Sized, + F: FnMut(Self::Item) -> bool,

    Tests if every element of the iterator matches a predicate. Read more
    1.0.0 · source§

    fn any<F>(&mut self, f: F) -> bool
    where + Self: Sized, + F: FnMut(Self::Item) -> bool,

    Tests if any element of the iterator matches a predicate. Read more
    1.0.0 · source§

    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
    where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

    Searches for an element of an iterator that satisfies a predicate. Read more
    1.30.0 · source§

    fn find_map<B, F>(&mut self, f: F) -> Option<B>
    where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

    Applies function to the elements of iterator and returns +the first non-none result. Read more
    source§

    fn try_find<F, R>( &mut self, f: F -) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere - Self: Sized, - F: FnMut(&Self::Item) -> R, - R: Try<Output = bool>, - <R as Try>::Residual: Residual<Option<Self::Item>>,

    🔬This is a nightly-only experimental API. (try_find)
    Applies function to the elements of iterator and returns -the first true result or the first error. Read more
    1.0.0 · source§

    fn position<P>(&mut self, predicate: P) -> Option<usize>where - Self: Sized, - P: FnMut(Self::Item) -> bool,

    Searches for an element in an iterator, returning its index. Read more
    1.6.0 · source§

    fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where - B: Ord, - Self: Sized, - F: FnMut(&Self::Item) -> B,

    Returns the element that gives the maximum value from the -specified function. Read more
    1.15.0 · source§

    fn max_by<F>(self, compare: F) -> Option<Self::Item>where - Self: Sized, - F: FnMut(&Self::Item, &Self::Item) -> Ordering,

    Returns the element that gives the maximum value with respect to the -specified comparison function. Read more
    1.6.0 · source§

    fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where - B: Ord, - Self: Sized, - F: FnMut(&Self::Item) -> B,

    Returns the element that gives the minimum value from the -specified function. Read more
    1.15.0 · source§

    fn min_by<F>(self, compare: F) -> Option<Self::Item>where - Self: Sized, - F: FnMut(&Self::Item, &Self::Item) -> Ordering,

    Returns the element that gives the minimum value with respect to the -specified comparison function. Read more
    1.0.0 · source§

    fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where - FromA: Default + Extend<A>, - FromB: Default + Extend<B>, - Self: Sized + Iterator<Item = (A, B)>,

    Converts an iterator of pairs into a pair of containers. Read more
    1.36.0 · source§

    fn copied<'a, T>(self) -> Copied<Self>where - T: 'a + Copy, - Self: Sized + Iterator<Item = &'a T>,

    Creates an iterator which copies all of its elements. Read more
    1.0.0 · source§

    fn cloned<'a, T>(self) -> Cloned<Self>where - T: 'a + Clone, - Self: Sized + Iterator<Item = &'a T>,

    Creates an iterator which clones all of its elements. Read more
    source§

    fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where - Self: Sized,

    🔬This is a nightly-only experimental API. (iter_array_chunks)
    Returns an iterator over N elements of the iterator at a time. Read more
    1.11.0 · source§

    fn sum<S>(self) -> Swhere - Self: Sized, - S: Sum<Self::Item>,

    Sums the elements of an iterator. Read more
    1.11.0 · source§

    fn product<P>(self) -> Pwhere - Self: Sized, - P: Product<Self::Item>,

    Iterates over the entire iterator, multiplying all the elements Read more
    source§

    fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere - Self: Sized, - I: IntoIterator, - F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

    🔬This is a nightly-only experimental API. (iter_order_by)
    Lexicographically compares the elements of this Iterator with those -of another with respect to the specified comparison function. Read more
    1.5.0 · source§

    fn partial_cmp<I>(self, other: I) -> Option<Ordering>where - I: IntoIterator, - Self::Item: PartialOrd<<I as IntoIterator>::Item>, - Self: Sized,

    Lexicographically compares the PartialOrd elements of -this Iterator with those of another. The comparison works like short-circuit +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
    where + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,
    🔬This is a nightly-only experimental API. (try_find)
    Applies function to the elements of iterator and returns +the first true result or the first error. Read more
    1.0.0 · source§

    fn position<P>(&mut self, predicate: P) -> Option<usize>
    where + Self: Sized, + P: FnMut(Self::Item) -> bool,

    Searches for an element in an iterator, returning its index. Read more
    1.6.0 · source§

    fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
    where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

    Returns the element that gives the maximum value from the +specified function. Read more
    1.15.0 · source§

    fn max_by<F>(self, compare: F) -> Option<Self::Item>
    where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

    Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
    1.6.0 · source§

    fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
    where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

    Returns the element that gives the minimum value from the +specified function. Read more
    1.15.0 · source§

    fn min_by<F>(self, compare: F) -> Option<Self::Item>
    where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

    Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
    1.0.0 · source§

    fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
    where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

    Converts an iterator of pairs into a pair of containers. Read more
    1.36.0 · source§

    fn copied<'a, T>(self) -> Copied<Self>
    where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

    Creates an iterator which copies all of its elements. Read more
    1.0.0 · source§

    fn cloned<'a, T>(self) -> Cloned<Self>
    where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

    Creates an iterator which clones all of its elements. Read more
    source§

    fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
    where + Self: Sized,

    🔬This is a nightly-only experimental API. (iter_array_chunks)
    Returns an iterator over N elements of the iterator at a time. Read more
    1.11.0 · source§

    fn sum<S>(self) -> S
    where + Self: Sized, + S: Sum<Self::Item>,

    Sums the elements of an iterator. Read more
    1.11.0 · source§

    fn product<P>(self) -> P
    where + Self: Sized, + P: Product<Self::Item>,

    Iterates over the entire iterator, multiplying all the elements Read more
    source§

    fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
    where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

    🔬This is a nightly-only experimental API. (iter_order_by)
    Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
    1.5.0 · source§

    fn partial_cmp<I>(self, other: I) -> Option<Ordering>
    where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

    Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit evaluation, returning a result without comparing the remaining elements. -As soon as an order can be determined, the evaluation stops and a result is returned. Read more
    source§

    fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where - Self: Sized, - I: IntoIterator, - F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

    🔬This is a nightly-only experimental API. (iter_order_by)
    Lexicographically compares the elements of this Iterator with those -of another with respect to the specified comparison function. Read more
    1.5.0 · source§

    fn eq<I>(self, other: I) -> boolwhere - I: IntoIterator, - Self::Item: PartialEq<<I as IntoIterator>::Item>, - Self: Sized,

    Determines if the elements of this Iterator are equal to those of -another. Read more
    source§

    fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere - Self: Sized, - I: IntoIterator, - F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

    🔬This is a nightly-only experimental API. (iter_order_by)
    Determines if the elements of this Iterator are equal to those of -another with respect to the specified equality function. Read more
    1.5.0 · source§

    fn ne<I>(self, other: I) -> boolwhere - I: IntoIterator, - Self::Item: PartialEq<<I as IntoIterator>::Item>, - Self: Sized,

    Determines if the elements of this Iterator are not equal to those of -another. Read more
    1.5.0 · source§

    fn lt<I>(self, other: I) -> boolwhere - I: IntoIterator, - Self::Item: PartialOrd<<I as IntoIterator>::Item>, - Self: Sized,

    Determines if the elements of this Iterator are lexicographically -less than those of another. Read more
    1.5.0 · source§

    fn le<I>(self, other: I) -> boolwhere - I: IntoIterator, - Self::Item: PartialOrd<<I as IntoIterator>::Item>, - Self: Sized,

    Determines if the elements of this Iterator are lexicographically -less or equal to those of another. Read more
    1.5.0 · source§

    fn gt<I>(self, other: I) -> boolwhere - I: IntoIterator, - Self::Item: PartialOrd<<I as IntoIterator>::Item>, - Self: Sized,

    Determines if the elements of this Iterator are lexicographically -greater than those of another. Read more
    1.5.0 · source§

    fn ge<I>(self, other: I) -> boolwhere - I: IntoIterator, - Self::Item: PartialOrd<<I as IntoIterator>::Item>, - Self: Sized,

    Determines if the elements of this Iterator are lexicographically -greater than or equal to those of another. Read more
    source§

    fn is_sorted_by<F>(self, compare: F) -> boolwhere - Self: Sized, - F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

    🔬This is a nightly-only experimental API. (is_sorted)
    Checks if the elements of this iterator are sorted using the given comparator function. Read more
    source§

    fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere - Self: Sized, - F: FnMut(Self::Item) -> K, - K: PartialOrd<K>,

    🔬This is a nightly-only experimental API. (is_sorted)
    Checks if the elements of this iterator are sorted using the given key extraction -function. Read more

    Auto Trait Implementations§

    §

    impl<R> RefUnwindSafe for FastqReader<R>where - R: RefUnwindSafe,

    §

    impl<R> Send for FastqReader<R>where - R: Send,

    §

    impl<R> Sync for FastqReader<R>where - R: Sync,

    §

    impl<R> Unpin for FastqReader<R>where - R: Unpin,

    §

    impl<R> UnwindSafe for FastqReader<R>where - R: UnwindSafe,

    Blanket Implementations§

    source§

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

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for Twhere - T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for Twhere - T: ?Sized,

    source§

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

    Mutably borrows from an owned value. 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 Twhere - U: From<T>,

    source§

    fn into(self) -> U

    Calls U::from(self).

    +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
    source§

    fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
    where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

    🔬This is a nightly-only experimental API. (iter_order_by)
    Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
    1.5.0 · source§

    fn eq<I>(self, other: I) -> bool
    where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

    Determines if the elements of this Iterator are equal to those of +another. Read more
    source§

    fn eq_by<I, F>(self, other: I, eq: F) -> bool
    where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

    🔬This is a nightly-only experimental API. (iter_order_by)
    Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
    1.5.0 · source§

    fn ne<I>(self, other: I) -> bool
    where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

    Determines if the elements of this Iterator are not equal to those of +another. Read more
    1.5.0 · source§

    fn lt<I>(self, other: I) -> bool
    where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

    Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
    1.5.0 · source§

    fn le<I>(self, other: I) -> bool
    where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

    Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
    1.5.0 · source§

    fn gt<I>(self, other: I) -> bool
    where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

    Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
    1.5.0 · source§

    fn ge<I>(self, other: I) -> bool
    where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

    Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
    source§

    fn is_sorted_by<F>(self, compare: F) -> bool
    where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> bool,

    🔬This is a nightly-only experimental API. (is_sorted)
    Checks if the elements of this iterator are sorted using the given comparator function. Read more
    source§

    fn is_sorted_by_key<F, K>(self, f: F) -> bool
    where + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd,

    🔬This is a nightly-only experimental API. (is_sorted)
    Checks if the elements of this iterator are sorted using the given key extraction +function. Read more

    Auto Trait Implementations§

    §

    impl<R> RefUnwindSafe for FastqReader<R>
    where + R: RefUnwindSafe,

    §

    impl<R> Send for FastqReader<R>
    where + R: Send,

    §

    impl<R> Sync for FastqReader<R>
    where + R: Sync,

    §

    impl<R> Unpin for FastqReader<R>
    where + R: Unpin,

    §

    impl<R> UnwindSafe for FastqReader<R>
    where + R: UnwindSafe,

    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> 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<I> IntoIterator for Iwhere - I: Iterator,

    §

    type Item = <I as Iterator>::Item

    The type of the elements being iterated over.
    §

    type IntoIter = I

    Which kind of iterator are we turning this into?
    const: unstable · source§

    fn into_iter(self) -> I

    Creates an iterator from a value. Read more
    source§

    impl<I> IteratorRandom for Iwhere - I: Iterator,

    source§

    fn choose<R>(self, rng: &mut R) -> Option<Self::Item>where - R: Rng + ?Sized,

    Choose one element at random from the iterator. If you have a slice, +From<T> for U chooses to do.

    +
    source§

    impl<I> IntoIterator for I
    where + I: Iterator,

    §

    type Item = <I as Iterator>::Item

    The type of the elements being iterated over.
    §

    type IntoIter = I

    Which kind of iterator are we turning this into?
    const: unstable · source§

    fn into_iter(self) -> I

    Creates an iterator from a value. Read more
    source§

    impl<I> IteratorRandom for I
    where + I: Iterator,

    source§

    fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
    where + R: Rng + ?Sized,

    Choose one element at random from the iterator. If you have a slice, it’s significantly faster to call the choose or choose_mut -functions using the slice instead. Read more
    source§

    fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usizewhere - R: Rng + ?Sized,

    Collects amount values at random from the iterator into a supplied -buffer. Read more
    source§

    fn choose_multiple<R>( - self, - rng: &mut R, - amount: usize -) -> Vec<Self::Item, Global>where - R: Rng + ?Sized,

    Collects amount values at random from the iterator into a vector. Read more
    source§

    impl<T, U> TryFrom<U> for Twhere - U: Into<T>,

    §

    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 Twhere - U: TryFrom<T>,

    §

    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.
    \ No newline at end of file +functions using the slice instead. Read more
    source§

    fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usize
    where + R: Rng + ?Sized,

    Collects amount values at random from the iterator into a supplied +buffer. Read more
    source§

    fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
    where + R: Rng + ?Sized,

    Collects amount values at random from the iterator into a vector. Read more
    source§

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

    §

    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>,

    §

    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.
    \ No newline at end of file diff --git a/docs/fasten/io/index.html b/docs/fasten/io/index.html index 83eef4f3..fa8e7d9b 100644 --- a/docs/fasten/io/index.html +++ b/docs/fasten/io/index.html @@ -1,2 +1,3 @@ -fasten::io - Rust

    Module fasten::io

    source ·
    Expand description

    input/output methods

    -

    Modules

    \ No newline at end of file +fasten::io - Rust +

    Module fasten::io

    source ·
    Expand description

    input/output methods

    +

    Modules§

    \ No newline at end of file diff --git a/docs/fasten/io/seq/index.html b/docs/fasten/io/seq/index.html index 89a202a9..0d35e678 100644 --- a/docs/fasten/io/seq/index.html +++ b/docs/fasten/io/seq/index.html @@ -1 +1,2 @@ -fasten::io::seq - Rust

    Module fasten::io::seq

    source ·

    Structs

    • A sequence struct that contains the ID, sequence, and quality cigar line

    Traits

    \ No newline at end of file +fasten::io::seq - Rust +

    Module fasten::io::seq

    source ·

    Structs§

    • A sequence struct that contains the ID, sequence, and quality cigar line

    Traits§

    \ No newline at end of file diff --git a/docs/fasten/io/seq/struct.Seq.html b/docs/fasten/io/seq/struct.Seq.html index c797fb56..a1823309 100644 --- a/docs/fasten/io/seq/struct.Seq.html +++ b/docs/fasten/io/seq/struct.Seq.html @@ -1,29 +1,30 @@ -Seq in fasten::io::seq - Rust

    Struct fasten::io::seq::Seq

    source ·
    pub struct Seq {
    -    pub id: String,
    -    pub seq: String,
    -    pub qual: String,
    -    pub pairid: String,
    -    pub thresholds: HashMap<String, f32>,
    +Seq in fasten::io::seq - Rust
    +    

    Struct fasten::io::seq::Seq

    source ·
    pub struct Seq {
    +    pub id: String,
    +    pub seq: String,
    +    pub qual: String,
    +    pub pairid: String,
    +    pub thresholds: HashMap<String, f32>,
     }
    Expand description

    A sequence struct that contains the ID, sequence, and quality cigar line

    -

    Fields§

    §id: String§seq: String§qual: String§pairid: String§thresholds: HashMap<String, f32>

    Trait Implementations§

    source§

    impl Cleanable for Seq

    source§

    fn new(id: &String, seq: &String, qual: &String) -> Seq

    Make a new cleanable sequence object

    +

    Fields§

    §id: String§seq: String§qual: String§pairid: String§thresholds: HashMap<String, f32>

    Trait Implementations§

    source§

    impl Cleanable for Seq

    source§

    fn new(id: &String, seq: &String, qual: &String) -> Seq

    Make a new cleanable sequence object

    source§

    fn blank() -> Seq

    Make a blank sequence object.

    -
    source§

    fn is_blank(&self) -> bool

    Determine if it is a blank sequence.

    -
    source§

    fn from_string(seq_str: &String) -> Seq

    Create a sequence object from a string. +

    source§

    fn is_blank(&self) -> bool

    Determine if it is a blank sequence.

    +
    source§

    fn from_string(seq_str: &String) -> Seq

    Create a sequence object from a string. TODO make it more like the careful method than quick.

    -
    source§

    fn sanitize_id(id: &String) -> String

    Read an identifier and return a cleaned version, +

    source§

    fn sanitize_id(id: &String) -> String

    Read an identifier and return a cleaned version, e.g., removing @ in a fastq identifier.

    source§

    fn lower_ambiguity_q(&mut self)

    Alter any ambiguity site with a quality=0

    source§

    fn trim(&mut self)

    Trim the ends of reads with low quality

    -
    source§

    fn is_high_quality(&mut self) -> bool

    Reports bool whether the read passes thresholds.

    -
    source§

    fn to_string(&self) -> String

    Make a String object
    source§

    fn print(&self)

    Print the result of to_string()
    source§

    impl Clone for Seq

    source§

    fn clone(&self) -> Seq

    Returns a copy 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 Debug for Seq

    source§

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

    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    §

    impl RefUnwindSafe for Seq

    §

    impl Send for Seq

    §

    impl Sync for Seq

    §

    impl Unpin for Seq

    §

    impl UnwindSafe for Seq

    Blanket Implementations§

    source§

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

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for Twhere - T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for Twhere - T: ?Sized,

    source§

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

    Mutably borrows from an owned value. 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 Twhere - U: From<T>,

    source§

    fn into(self) -> U

    Calls U::from(self).

    +
    source§

    fn is_high_quality(&mut self) -> bool

    Reports bool whether the read passes thresholds.

    +
    source§

    fn to_string(&self) -> String

    Make a String object
    source§

    fn print(&self)

    Print the result of to_string()
    source§

    impl Clone for Seq

    source§

    fn clone(&self) -> Seq

    Returns a copy 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 Debug for Seq

    source§

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

    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    §

    impl RefUnwindSafe for Seq

    §

    impl Send for Seq

    §

    impl Sync for Seq

    §

    impl Unpin for Seq

    §

    impl UnwindSafe for Seq

    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> 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 Twhere - T: Clone,

    §

    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 Twhere - U: Into<T>,

    §

    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 Twhere - U: TryFrom<T>,

    §

    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.
    \ No newline at end of file +From<T> for U chooses to do.

    +
    source§

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

    §

    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>,

    §

    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>,

    §

    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.
    \ No newline at end of file diff --git a/docs/fasten/io/seq/trait.Cleanable.html b/docs/fasten/io/seq/trait.Cleanable.html index 72f4d413..69cc33c1 100644 --- a/docs/fasten/io/seq/trait.Cleanable.html +++ b/docs/fasten/io/seq/trait.Cleanable.html @@ -1,24 +1,25 @@ -Cleanable in fasten::io::seq - Rust

    Trait fasten::io::seq::Cleanable

    source ·
    pub trait Cleanable {
    +Cleanable in fasten::io::seq - Rust
    +    

    Trait fasten::io::seq::Cleanable

    source ·
    pub trait Cleanable {
         // Required methods
    -    fn new(id: &String, seq: &String, qual: &String) -> Seq;
    +    fn new(id: &String, seq: &String, qual: &String) -> Seq;
         fn blank() -> Seq;
    -    fn is_blank(&self) -> bool;
    -    fn from_string(seq_str: &String) -> Seq;
    -    fn sanitize_id(id: &String) -> String;
    +    fn is_blank(&self) -> bool;
    +    fn from_string(seq_str: &String) -> Seq;
    +    fn sanitize_id(id: &String) -> String;
         fn lower_ambiguity_q(&mut self);
         fn trim(&mut self);
    -    fn is_high_quality(&mut self) -> bool;
    -    fn to_string(&self) -> String;
    +    fn is_high_quality(&mut self) -> bool;
    +    fn to_string(&self) -> String;
         fn print(&self);
     }
    Expand description

    A sequence that can be cleaned

    -

    Required Methods§

    source

    fn new(id: &String, seq: &String, qual: &String) -> Seq

    new sequence object

    +

    Required Methods§

    source

    fn new(id: &String, seq: &String, qual: &String) -> Seq

    new sequence object

    source

    fn blank() -> Seq

    Make a blank sequence object.

    -
    source

    fn is_blank(&self) -> bool

    Determine if it is a blank sequence.

    -
    source

    fn from_string(seq_str: &String) -> Seq

    Make a seq object from a String.

    -
    source

    fn sanitize_id(id: &String) -> String

    sanitize an identifier string

    +
    source

    fn is_blank(&self) -> bool

    Determine if it is a blank sequence.

    +
    source

    fn from_string(seq_str: &String) -> Seq

    Make a seq object from a String.

    +
    source

    fn sanitize_id(id: &String) -> String

    sanitize an identifier string

    source

    fn lower_ambiguity_q(&mut self)

    lower any low quality base to a zero and “N”

    source

    fn trim(&mut self)

    Trim sequences based on quality

    -
    source

    fn is_high_quality(&mut self) -> bool

    Reports bool whether the read passes thresholds.

    -
    source

    fn to_string(&self) -> String

    Make a String object

    +
    source

    fn is_high_quality(&mut self) -> bool

    Reports bool whether the read passes thresholds.

    +
    source

    fn to_string(&self) -> String

    Make a String object

    source

    fn print(&self)

    Print the result of to_string()

    -

    Implementors§

    \ No newline at end of file +

    Object Safety§

    This trait is not object safe.

    Implementors§

    \ No newline at end of file diff --git a/docs/fasten/macro.print.html b/docs/fasten/macro.print.html index f1b5695c..25115c71 100644 --- a/docs/fasten/macro.print.html +++ b/docs/fasten/macro.print.html @@ -1,4 +1,5 @@ -print in fasten - Rust

    Macro fasten::print

    source ·
    macro_rules! print {
    +print in fasten - Rust
    +    

    Macro fasten::print

    source ·
    macro_rules! print {
         ($($arg:tt)*) => { ... };
     }
    Expand description

    Rewrite print!() so that it doesn’t panic on broken pipe.

    diff --git a/docs/fasten/sidebar-items.js b/docs/fasten/sidebar-items.js index e5b1111d..b36cbeb0 100644 --- a/docs/fasten/sidebar-items.js +++ b/docs/fasten/sidebar-items.js @@ -1 +1 @@ -window.SIDEBAR_ITEMS = {"fn":["eexit","fasten_base_options","fasten_base_options_matches","logmsg"],"macro":["print"],"mod":["io"]}; \ No newline at end of file +window.SIDEBAR_ITEMS = {"fn":["eexit","fasten_base_options","fasten_base_options_matches","logmsg","reverse_complement"],"macro":["print"],"mod":["io"]}; \ No newline at end of file diff --git a/docs/fasten_clean/all.html b/docs/fasten_clean/all.html index bc4938c0..baeb1bc3 100644 --- a/docs/fasten_clean/all.html +++ b/docs/fasten_clean/all.html @@ -1 +1,2 @@ -List of all items in this crate

    List of all items

    Functions

    \ No newline at end of file +List of all items in this crate +

    List of all items

    Functions

    \ No newline at end of file diff --git a/docs/fasten_clean/fn.avg_quality.html b/docs/fasten_clean/fn.avg_quality.html index 6adac271..42148b90 100644 --- a/docs/fasten_clean/fn.avg_quality.html +++ b/docs/fasten_clean/fn.avg_quality.html @@ -1,3 +1,4 @@ -avg_quality in fasten_clean - Rust

    Function fasten_clean::avg_quality

    source ·
    pub(crate) fn avg_quality(qual: &String) -> f32
    Expand description

    Determine average quality of a qual cigar string, +avg_quality in fasten_clean - Rust

    +

    Function fasten_clean::avg_quality

    source ·
    pub(crate) fn avg_quality(qual: &String) -> f32
    Expand description

    Determine average quality of a qual cigar string, e.g., let q:f32 = avg_quality(“AABC!…”)

    \ No newline at end of file diff --git a/docs/fasten_clean/fn.main.html b/docs/fasten_clean/fn.main.html index f81a3a37..3ad2489e 100644 --- a/docs/fasten_clean/fn.main.html +++ b/docs/fasten_clean/fn.main.html @@ -1 +1,2 @@ -main in fasten_clean - Rust

    Function fasten_clean::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_clean - Rust +

    Function fasten_clean::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_clean/fn.trim.html b/docs/fasten_clean/fn.trim.html index 49ca90f5..e98d3f57 100644 --- a/docs/fasten_clean/fn.trim.html +++ b/docs/fasten_clean/fn.trim.html @@ -1,6 +1,7 @@ -trim in fasten_clean - Rust

    Function fasten_clean::trim

    source ·
    pub(crate) fn trim(
    -    seq: &String,
    -    qual: &String,
    -    min_qual: u8
    -) -> (String, String)
    Expand description

    Trim the ends of reads with low quality

    +trim in fasten_clean - Rust +

    Function fasten_clean::trim

    source ·
    pub(crate) fn trim(
    +    seq: &String,
    +    qual: &String,
    +    min_qual: u8
    +) -> (String, String)
    Expand description

    Trim the ends of reads with low quality

    \ No newline at end of file diff --git a/docs/fasten_clean/index.html b/docs/fasten_clean/index.html index bf8c6870..56413e09 100644 --- a/docs/fasten_clean/index.html +++ b/docs/fasten_clean/index.html @@ -1,11 +1,13 @@ -fasten_clean - Rust

    Crate fasten_clean

    source ·
    Expand description

    Trim and filter reads

    -

    Examples

    cat testdata/four_lines.fastq | \
    +fasten_clean - Rust
    +    

    Crate fasten_clean

    source ·
    Expand description

    Trim and filter reads

    +

    §Examples

    cat testdata/four_lines.fastq | \
       fasten_clean > out.fastq
    -

    more options

    cat testdata | \
    +

    §more options

    cat testdata | \
       fasten_clean --min-avg-quality 25 --min-trim-quality 25 \
       > out.fastq
      
    -

    Usage

    Usage: fasten_clean [-h] [-n INT] [-p] [-v] [--min-length INT] [--min-avg-quality FLOAT] [--min-trim-quality INT]
    +

    §Usage

    Usage: fasten_clean [-h] [-n INT] [-p] [-v] [--min-length INT] [--min-avg-quality FLOAT] [--min-trim-quality INT]
     
        Options:
            -h, --help          Print this help menu.
    @@ -19,5 +21,5 @@ 

    Examples

    Functions

    • Determine average quality of a qual cigar string, +

    Functions§

    • Determine average quality of a qual cigar string, e.g., let q:f32 = avg_quality(“AABC!…”)
    • main 🔒
    • trim 🔒
      Trim the ends of reads with low quality
    \ No newline at end of file diff --git a/docs/fasten_combine/all.html b/docs/fasten_combine/all.html index 7860dd83..5221badc 100644 --- a/docs/fasten_combine/all.html +++ b/docs/fasten_combine/all.html @@ -1 +1,2 @@ -List of all items in this crate

    List of all items

    Functions

    Constants

    \ No newline at end of file +List of all items in this crate +

    List of all items

    Functions

    Constants

    \ No newline at end of file diff --git a/docs/fasten_combine/constant.READ_SEPARATOR.html b/docs/fasten_combine/constant.READ_SEPARATOR.html index 0d6f5fba..d54db939 100644 --- a/docs/fasten_combine/constant.READ_SEPARATOR.html +++ b/docs/fasten_combine/constant.READ_SEPARATOR.html @@ -1,3 +1,4 @@ -READ_SEPARATOR in fasten_combine - Rust
    pub(crate) const READ_SEPARATOR: char = '~';
    Expand description

    Glues together paired end reads internally and is a +READ_SEPARATOR in fasten_combine - Rust

    +
    pub(crate) const READ_SEPARATOR: char = '~';
    Expand description

    Glues together paired end reads internally and is a character not expected in any read

    \ No newline at end of file diff --git a/docs/fasten_combine/constant.TEN.html b/docs/fasten_combine/constant.TEN.html index e91b60fb..84ed7037 100644 --- a/docs/fasten_combine/constant.TEN.html +++ b/docs/fasten_combine/constant.TEN.html @@ -1,3 +1,4 @@ -TEN in fasten_combine - Rust

    Constant fasten_combine::TEN

    source ·
    pub(crate) const TEN: f32 = 10.0;
    Expand description

    need this constant because the compiler had a problem +TEN in fasten_combine - Rust

    +

    Constant fasten_combine::TEN

    source ·
    pub(crate) const TEN: f32 = 10.0;
    Expand description

    need this constant because the compiler had a problem with the syntax 10.0.pow()

    \ No newline at end of file diff --git a/docs/fasten_combine/fn.combine_error_vectors.html b/docs/fasten_combine/fn.combine_error_vectors.html index b6fbdfad..350d90be 100644 --- a/docs/fasten_combine/fn.combine_error_vectors.html +++ b/docs/fasten_combine/fn.combine_error_vectors.html @@ -1,7 +1,8 @@ -combine_error_vectors in fasten_combine - Rust
    pub(crate) fn combine_error_vectors(
    -    errors1: &Vec<f32>,
    -    errors2: &Vec<f32>
    -) -> Vec<f32>
    Expand description

    Combines vectors of error probabilities +combine_error_vectors in fasten_combine - Rust

    +
    pub(crate) fn combine_error_vectors(
    +    errors1: &Vec<f32>,
    +    errors2: &Vec<f32>
    +) -> Vec<f32>
    Expand description

    Combines vectors of error probabilities such that the rate of error is probability of error from vector one times the probability of error from vector two.

    diff --git a/docs/fasten_combine/fn.main.html b/docs/fasten_combine/fn.main.html index 99e59012..48b3e466 100644 --- a/docs/fasten_combine/fn.main.html +++ b/docs/fasten_combine/fn.main.html @@ -1 +1,2 @@ -main in fasten_combine - Rust

    Function fasten_combine::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_combine - Rust +

    Function fasten_combine::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_combine/index.html b/docs/fasten_combine/index.html index 411d7ee0..b23ab774 100644 --- a/docs/fasten_combine/index.html +++ b/docs/fasten_combine/index.html @@ -1,8 +1,10 @@ -fasten_combine - Rust

    Crate fasten_combine

    source ·
    Expand description

    Collapse identical reads into single reads, recalculating quality values. +fasten_combine - Rust

    +

    Crate fasten_combine

    source ·
    Expand description

    Collapse identical reads into single reads, recalculating quality values. If paired end, then each set of reads must be identical to be collapsed. Warning: due to multiple reads collapsing into one, read identifiers will be reconstituted.

    -

    Examples

    cat testdata/four_reads | fasten_combine > combined.fastq
    -

    Usage

    Usage: fasten_combine [-h] [-n INT] [-p] [-v] [--max-qual-char CHAR] [--min-qual-char CHAR]
    +

    §Examples

    cat testdata/four_reads | fasten_combine > combined.fastq
    +

    §Usage

    Usage: fasten_combine [-h] [-n INT] [-p] [-v] [--max-qual-char CHAR] [--min-qual-char CHAR]
     
     Options:
         -h, --help          Print this help menu.
    @@ -15,9 +17,9 @@ 

    Examples

    Constants

    • Glues together paired end reads internally and is a +

    Constants§

    • Glues together paired end reads internally and is a character not expected in any read
    • TEN 🔒
      need this constant because the compiler had a problem -with the syntax 10.0.pow()

    Functions

    Functions§

    • Combines vectors of error probabilities such that the rate of error is probability of error from vector one times the probability of error from vector two.
    • main 🔒
    \ No newline at end of file diff --git a/docs/fasten_convert/all.html b/docs/fasten_convert/all.html index b346911e..f76d2076 100644 --- a/docs/fasten_convert/all.html +++ b/docs/fasten_convert/all.html @@ -1 +1,2 @@ -List of all items in this crate
    \ No newline at end of file +List of all items in this crate +
    \ No newline at end of file diff --git a/docs/fasten_convert/fn.main.html b/docs/fasten_convert/fn.main.html index ac9337ee..6df53e3c 100644 --- a/docs/fasten_convert/fn.main.html +++ b/docs/fasten_convert/fn.main.html @@ -1 +1,2 @@ -main in fasten_convert - Rust

    Function fasten_convert::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_convert - Rust +

    Function fasten_convert::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_convert/fn.read_fasta.html b/docs/fasten_convert/fn.read_fasta.html index 039b03f5..74b161f7 100644 --- a/docs/fasten_convert/fn.read_fasta.html +++ b/docs/fasten_convert/fn.read_fasta.html @@ -1,2 +1,3 @@ -read_fasta in fasten_convert - Rust

    Function fasten_convert::read_fasta

    source ·
    pub(crate) fn read_fasta(tx: Sender<FastenSeq>, paired_end: bool)
    Expand description

    Read fasta from stdin and transmit it to a channel

    +read_fasta in fasten_convert - Rust +

    Function fasten_convert::read_fasta

    source ·
    pub(crate) fn read_fasta(tx: Sender<FastenSeq>, paired_end: bool)
    Expand description

    Read fasta from stdin and transmit it to a channel

    \ No newline at end of file diff --git a/docs/fasten_convert/fn.read_fastq.html b/docs/fasten_convert/fn.read_fastq.html index f0b0f5e0..edf3e0c5 100644 --- a/docs/fasten_convert/fn.read_fastq.html +++ b/docs/fasten_convert/fn.read_fastq.html @@ -1,2 +1,3 @@ -read_fastq in fasten_convert - Rust

    Function fasten_convert::read_fastq

    source ·
    pub(crate) fn read_fastq(tx: Sender<FastenSeq>, paired_end: bool)
    Expand description

    Read fastq from stdin and transmit it to a channel

    +read_fastq in fasten_convert - Rust +

    Function fasten_convert::read_fastq

    source ·
    pub(crate) fn read_fastq(tx: Sender<FastenSeq>, paired_end: bool)
    Expand description

    Read fastq from stdin and transmit it to a channel

    \ No newline at end of file diff --git a/docs/fasten_convert/fn.read_sam.html b/docs/fasten_convert/fn.read_sam.html index 7bc838ba..6d3b958d 100644 --- a/docs/fasten_convert/fn.read_sam.html +++ b/docs/fasten_convert/fn.read_sam.html @@ -1,2 +1,3 @@ -read_sam in fasten_convert - Rust

    Function fasten_convert::read_sam

    source ·
    pub(crate) fn read_sam(tx: Sender<FastenSeq>, paired_end: bool)
    Expand description

    Read sam from stdin and transmit it to a channel

    +read_sam in fasten_convert - Rust +

    Function fasten_convert::read_sam

    source ·
    pub(crate) fn read_sam(tx: Sender<FastenSeq>, paired_end: bool)
    Expand description

    Read sam from stdin and transmit it to a channel

    \ No newline at end of file diff --git a/docs/fasten_convert/fn.write_fasta.html b/docs/fasten_convert/fn.write_fasta.html index d6ed1a37..f1e3ced5 100644 --- a/docs/fasten_convert/fn.write_fasta.html +++ b/docs/fasten_convert/fn.write_fasta.html @@ -1,2 +1,3 @@ -write_fasta in fasten_convert - Rust
    pub(crate) fn write_fasta(rx: Receiver<FastenSeq>)
    Expand description

    Read from a channel and print as fasta

    +write_fasta in fasten_convert - Rust +
    pub(crate) fn write_fasta(rx: Receiver<FastenSeq>)
    Expand description

    Read from a channel and print as fasta

    \ No newline at end of file diff --git a/docs/fasten_convert/fn.write_fastq.html b/docs/fasten_convert/fn.write_fastq.html index 3ea7477a..7105d2f4 100644 --- a/docs/fasten_convert/fn.write_fastq.html +++ b/docs/fasten_convert/fn.write_fastq.html @@ -1,2 +1,3 @@ -write_fastq in fasten_convert - Rust
    pub(crate) fn write_fastq(rx: Receiver<FastenSeq>)
    Expand description

    Read from a channel and print as fastq

    +write_fastq in fasten_convert - Rust +
    pub(crate) fn write_fastq(rx: Receiver<FastenSeq>)
    Expand description

    Read from a channel and print as fastq

    \ No newline at end of file diff --git a/docs/fasten_convert/fn.write_sam.html b/docs/fasten_convert/fn.write_sam.html index 82286dc3..267307ea 100644 --- a/docs/fasten_convert/fn.write_sam.html +++ b/docs/fasten_convert/fn.write_sam.html @@ -1,2 +1,3 @@ -write_sam in fasten_convert - Rust

    Function fasten_convert::write_sam

    source ·
    pub(crate) fn write_sam(rx: Receiver<FastenSeq>)
    Expand description

    Read from a channel and print as sam

    +write_sam in fasten_convert - Rust +

    Function fasten_convert::write_sam

    source ·
    pub(crate) fn write_sam(rx: Receiver<FastenSeq>)
    Expand description

    Read from a channel and print as sam

    \ No newline at end of file diff --git a/docs/fasten_convert/index.html b/docs/fasten_convert/index.html index da36307b..a9d8c3a4 100644 --- a/docs/fasten_convert/index.html +++ b/docs/fasten_convert/index.html @@ -1,8 +1,10 @@ -fasten_convert - Rust

    Crate fasten_convert

    source ·
    Expand description

    Convert between different sequence formats

    -

    Examples

    Simple conversion

    cat file.fastq | fasten_convert -i fastq -o fasta > out.fasta
    -

    Convert to sam and then to bam

    cat file.fastq | fasten_convert -i fastq -o sam   | samtools view -bS > file.bam
    -

    Convert to fastq and then clean

    cat file.fasta | fasten_convert -i fasta -o fastq | fasten_clean > cleaned.fastq
    -

    Usage

    Usage: fasten_convert [-h] [-n INT] [-p] [-v] [-i FORMAT] [-o FORMAT]
    +fasten_convert - Rust
    +    

    Crate fasten_convert

    source ·
    Expand description

    Convert between different sequence formats

    +

    §Examples

    §Simple conversion

    cat file.fastq | fasten_convert -i fastq -o fasta > out.fasta
    +

    §Convert to sam and then to bam

    cat file.fastq | fasten_convert -i fastq -o sam   | samtools view -bS > file.bam
    +

    §Convert to fastq and then clean

    cat file.fasta | fasten_convert -i fasta -o fastq | fasten_clean > cleaned.fastq
    +

    §Usage

    Usage: fasten_convert [-h] [-n INT] [-p] [-v] [-i FORMAT] [-o FORMAT]
     
     Options:
         -h, --help          Print this help menu.
    @@ -14,4 +16,4 @@ 

    Examples

    Structs

    • FastenSeq 🔒
      Struct that can handle paired end reads

    Functions

    • main 🔒
    • read_fasta 🔒
      Read fasta from stdin and transmit it to a channel
    • read_fastq 🔒
      Read fastq from stdin and transmit it to a channel
    • read_sam 🔒
      Read sam from stdin and transmit it to a channel
    • Read from a channel and print as fasta
    • Read from a channel and print as fastq
    • write_sam 🔒
      Read from a channel and print as sam
    \ No newline at end of file +

    Structs§

    • FastenSeq 🔒
      Struct that can handle paired end reads

    Functions§

    • main 🔒
    • read_fasta 🔒
      Read fasta from stdin and transmit it to a channel
    • read_fastq 🔒
      Read fastq from stdin and transmit it to a channel
    • read_sam 🔒
      Read sam from stdin and transmit it to a channel
    • Read from a channel and print as fasta
    • Read from a channel and print as fastq
    • write_sam 🔒
      Read from a channel and print as sam
    \ No newline at end of file diff --git a/docs/fasten_convert/struct.FastenSeq.html b/docs/fasten_convert/struct.FastenSeq.html index ead24d6d..a3d6a9e8 100644 --- a/docs/fasten_convert/struct.FastenSeq.html +++ b/docs/fasten_convert/struct.FastenSeq.html @@ -1,24 +1,25 @@ -FastenSeq in fasten_convert - Rust
    pub(crate) struct FastenSeq {
    -    pub(crate) id1: String,
    -    pub(crate) seq1: String,
    -    pub(crate) qual1: String,
    -    pub(crate) id2: String,
    -    pub(crate) seq2: String,
    -    pub(crate) qual2: String,
    +FastenSeq in fasten_convert - Rust
    +    
    pub(crate) struct FastenSeq {
    +    pub(crate) id1: String,
    +    pub(crate) seq1: String,
    +    pub(crate) qual1: String,
    +    pub(crate) id2: String,
    +    pub(crate) seq2: String,
    +    pub(crate) qual2: String,
     }
    Expand description

    Struct that can handle paired end reads

    -

    Fields§

    §id1: String§seq1: String§qual1: String§id2: String§seq2: String§qual2: String

    Implementations§

    source§

    impl FastenSeq

    source

    pub(crate) fn new() -> FastenSeq

    a blank new object is a set of blank strings for each value

    -
    source

    pub(crate) fn as_fastq(&self) -> String

    Return a formatted string as a fastq entry

    -
    source

    pub(crate) fn as_fasta(&self) -> String

    Return a formatted string as a fasta entry

    -
    source

    pub(crate) fn as_sam(&self) -> String

    Return a formatted string as a sam entry

    -

    Trait Implementations§

    source§

    impl Clone for FastenSeq

    source§

    fn clone(&self) -> FastenSeq

    Returns a copy 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 Debug for FastenSeq

    source§

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

    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    Blanket Implementations§

    source§

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

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for Twhere - T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for Twhere - T: ?Sized,

    source§

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

    Mutably borrows from an owned value. 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 Twhere - U: From<T>,

    source§

    fn into(self) -> U

    Calls U::from(self).

    +

    Fields§

    §id1: String§seq1: String§qual1: String§id2: String§seq2: String§qual2: String

    Implementations§

    source§

    impl FastenSeq

    source

    pub(crate) fn new() -> FastenSeq

    a blank new object is a set of blank strings for each value

    +
    source

    pub(crate) fn as_fastq(&self) -> String

    Return a formatted string as a fastq entry

    +
    source

    pub(crate) fn as_fasta(&self) -> String

    Return a formatted string as a fasta entry

    +
    source

    pub(crate) fn as_sam(&self) -> String

    Return a formatted string as a sam entry

    +

    Trait Implementations§

    source§

    impl Clone for FastenSeq

    source§

    fn clone(&self) -> FastenSeq

    Returns a copy 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 Debug for FastenSeq

    source§

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

    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    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> 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 Twhere - T: Clone,

    §

    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 Twhere - U: Into<T>,

    §

    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 Twhere - U: TryFrom<T>,

    §

    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.
    \ No newline at end of file +From<T> for U chooses to do.

    +
    source§

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

    §

    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>,

    §

    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>,

    §

    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.
    \ No newline at end of file diff --git a/docs/fasten_inspect/all.html b/docs/fasten_inspect/all.html index 1cc01a67..5ed98233 100644 --- a/docs/fasten_inspect/all.html +++ b/docs/fasten_inspect/all.html @@ -1 +1,2 @@ -List of all items in this crate

    List of all items

    Functions

    \ No newline at end of file +List of all items in this crate +

    List of all items

    Functions

    \ No newline at end of file diff --git a/docs/fasten_inspect/fn.main.html b/docs/fasten_inspect/fn.main.html index 4a1b438a..1f9d3f95 100644 --- a/docs/fasten_inspect/fn.main.html +++ b/docs/fasten_inspect/fn.main.html @@ -1 +1,2 @@ -main in fasten_inspect - Rust

    Function fasten_inspect::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_inspect - Rust +

    Function fasten_inspect::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_inspect/fn.validate_reads.html b/docs/fasten_inspect/fn.validate_reads.html index ec32e2d6..4d042e76 100644 --- a/docs/fasten_inspect/fn.validate_reads.html +++ b/docs/fasten_inspect/fn.validate_reads.html @@ -1,5 +1,6 @@ -validate_reads in fasten_inspect - Rust
    pub(crate) fn validate_reads(
    -    lines_per_read: u8,
    +validate_reads in fasten_inspect - Rust
    +    
    pub(crate) fn validate_reads(
    +    lines_per_read: u8,
         seq_regex: Regex,
         qual_regex: Regex
     )
    Expand description

    marks up reads from stdin

    diff --git a/docs/fasten_inspect/index.html b/docs/fasten_inspect/index.html index a9900083..61890bb7 100644 --- a/docs/fasten_inspect/index.html +++ b/docs/fasten_inspect/index.html @@ -1,10 +1,12 @@ -fasten_inspect - Rust

    Crate fasten_inspect

    source ·
    Expand description

    Marks up your reads with useful information like read length

    -

    Examples

    Quick validation with stderr message

    cat file.fastq | fasten_inspect > markedup.fastq
    +fasten_inspect - Rust
    +    

    Crate fasten_inspect

    source ·
    Expand description

    Marks up your reads with useful information like read length

    +

    §Examples

    §Quick validation with stderr message

    cat file.fastq | fasten_inspect > markedup.fastq
     cat file.fastq | fasten_inspect --paired-end > markedup-paired.fastq
     

    The resulting marked-up fastq file will have deflines like

    @read0/1 id-at:1 seq-length:100 seq-invalid-chars: id-plus:1 qual-invalid-chars: avg-qual:20.93 qual-length:100 read-pair:1
    -

    Usage

    fasten_inspect: Marks up your reads with useful information like read length
    +

    §Usage

    fasten_inspect: Marks up your reads with useful information like read length
     
     Usage: fasten_inspect [-h] [-n INT] [-p] [--verbose] [--version]
     
    @@ -26,4 +28,4 @@ 

    Examples

    Functions

    \ No newline at end of file +

    Functions§

    \ No newline at end of file diff --git a/docs/fasten_kmer/all.html b/docs/fasten_kmer/all.html index 8627c0c7..b2189a0f 100644 --- a/docs/fasten_kmer/all.html +++ b/docs/fasten_kmer/all.html @@ -1 +1,2 @@ -List of all items in this crate
    \ No newline at end of file +List of all items in this crate +
    \ No newline at end of file diff --git a/docs/fasten_kmer/constant.READ_SEPARATOR.html b/docs/fasten_kmer/constant.READ_SEPARATOR.html index 7d4f6bac..80a7e1db 100644 --- a/docs/fasten_kmer/constant.READ_SEPARATOR.html +++ b/docs/fasten_kmer/constant.READ_SEPARATOR.html @@ -1,3 +1,4 @@ -READ_SEPARATOR in fasten_kmer - Rust
    pub(crate) const READ_SEPARATOR: char = '~';
    Expand description

    Glues together paired end reads internally and is a +READ_SEPARATOR in fasten_kmer - Rust

    +
    pub(crate) const READ_SEPARATOR: char = '~';
    Expand description

    Glues together paired end reads internally and is a character not expected in any read

    \ No newline at end of file diff --git a/docs/fasten_kmer/fn.count_kmers.html b/docs/fasten_kmer/fn.count_kmers.html index 958c9a51..0723e8e4 100644 --- a/docs/fasten_kmer/fn.count_kmers.html +++ b/docs/fasten_kmer/fn.count_kmers.html @@ -1,8 +1,9 @@ -count_kmers in fasten_kmer - Rust

    Function fasten_kmer::count_kmers

    source ·
    pub(crate) fn count_kmers(
    -    stdin: Stdin,
    -    kmer_length: usize,
    -    revcomp: bool,
    -    remember_reads: bool,
    -    paired_end: bool
    +count_kmers in fasten_kmer - Rust
    +    

    Function fasten_kmer::count_kmers

    source ·
    pub(crate) fn count_kmers(
    +    stdin: Stdin,
    +    kmer_length: usize,
    +    revcomp: bool,
    +    remember_reads: bool,
    +    paired_end: bool
     )
    Expand description

    Read fastq from stdin and count kmers

    \ No newline at end of file diff --git a/docs/fasten_kmer/fn.kmers_in_str.html b/docs/fasten_kmer/fn.kmers_in_str.html index e226aa97..a4b72f1a 100644 --- a/docs/fasten_kmer/fn.kmers_in_str.html +++ b/docs/fasten_kmer/fn.kmers_in_str.html @@ -1,7 +1,8 @@ -kmers_in_str in fasten_kmer - Rust

    Function fasten_kmer::kmers_in_str

    source ·
    pub(crate) fn kmers_in_str(
    -    seq: &str,
    -    kmer_length: usize,
    -    should_revcomp: bool
    -) -> HashMap<String, u32>
    Expand description

    Read a str of nucleotides and count kmers. +kmers_in_str in fasten_kmer - Rust

    +

    Function fasten_kmer::kmers_in_str

    source ·
    pub(crate) fn kmers_in_str(
    +    seq: &str,
    +    kmer_length: usize,
    +    should_revcomp: bool
    +) -> HashMap<String, u32>
    Expand description

    Read a str of nucleotides and count kmers. If should_revcomp is true, then will also count kmers on the opposite strand.

    \ No newline at end of file diff --git a/docs/fasten_kmer/fn.main.html b/docs/fasten_kmer/fn.main.html index 81509824..9ac78bba 100644 --- a/docs/fasten_kmer/fn.main.html +++ b/docs/fasten_kmer/fn.main.html @@ -1 +1,2 @@ -main in fasten_kmer - Rust

    Function fasten_kmer::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_kmer - Rust +

    Function fasten_kmer::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_kmer/fn.revcomp.html b/docs/fasten_kmer/fn.revcomp.html index 9fa4aa78..ed314469 100644 --- a/docs/fasten_kmer/fn.revcomp.html +++ b/docs/fasten_kmer/fn.revcomp.html @@ -1,2 +1,3 @@ -revcomp in fasten_kmer - Rust

    Function fasten_kmer::revcomp

    source ·
    pub(crate) fn revcomp(dna: &str) -> String
    Expand description

    reverse-complement a dna sequence

    +revcomp in fasten_kmer - Rust +

    Function fasten_kmer::revcomp

    source ·
    pub(crate) fn revcomp(dna: &str) -> String
    Expand description

    reverse-complement a dna sequence

    \ No newline at end of file diff --git a/docs/fasten_kmer/fn.switch_base.html b/docs/fasten_kmer/fn.switch_base.html index b70148cd..a9f3b18b 100644 --- a/docs/fasten_kmer/fn.switch_base.html +++ b/docs/fasten_kmer/fn.switch_base.html @@ -1,2 +1,3 @@ -switch_base in fasten_kmer - Rust

    Function fasten_kmer::switch_base

    source ·
    pub(crate) fn switch_base(c: char) -> char
    Expand description

    Complementary nucleotide for ACTGUN, case insensitive

    +switch_base in fasten_kmer - Rust +

    Function fasten_kmer::switch_base

    source ·
    pub(crate) fn switch_base(c: char) -> char
    Expand description

    Complementary nucleotide for ACTGUN, case insensitive

    \ No newline at end of file diff --git a/docs/fasten_kmer/index.html b/docs/fasten_kmer/index.html index 65ca3621..5bf6c733 100644 --- a/docs/fasten_kmer/index.html +++ b/docs/fasten_kmer/index.html @@ -1,19 +1,21 @@ -fasten_kmer - Rust

    Crate fasten_kmer

    source ·
    Expand description

    Counts kmers. +fasten_kmer - Rust

    +

    Crate fasten_kmer

    source ·
    Expand description

    Counts kmers. Each line is a kmer with two columns separated by tab: kmer, count Optional columns starting with column 3 are the reads that start with that kmer with a delimiter of ~

    -

    Examples

    +

    §Examples

    Counting kmers of 15. Using --paired-end will not matter here.

    cat testdata/four_reads.fastq | fasten_kmer -k 15 > 15mers.tsv
     

    Counting kmers and retaining reads

    cat testdata/four_reads.fastq | \
       fasten_kmer -k 15 --remember-reads > 15mers.tsv
    -

    Example output

    +

    §Example output

    First two lines of a kmer output where they contain reads

    TAGTGAATCCTTTTTCATAAA   39      @M03235:53:000000000-AHLTD:1:1113:23312:4764 1:N:0:6~TAGTGAATCCTTTTTCATAAAATCTTGCTTCAAAATTGCTAAGAGTTTATAAGCAAGAAGTGTTCCAAGTTTGCAAGATGAGGTGAGATTGTGTAAATAAGCTACAAAATTTTTAATTTAAGCCCTACAAGCTCTTAAATATCAAAAGCATTTTCTAAAATATGCAAAAATGTAAGCAAAATGTTTAAAGGAAAGTCGTGAAAAATGCTGAAAAAACTTTAAGAAGGAATTTTTTTACCCTAATCTTACTT~+~>AAA>DDFFFFFGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHGHHGHHHHHHHHFHHHHHGGHHHHHHHGHHHHHHGHHHHHHCHGHHFHHHHGHHHHHHHHHHHGHHHGHHHHHHHHHHHHHHHGHHHGHHFHGHFHHHHHHGHHHFHHHHHHHGHHHHHHHHGHHHHHHHHGHHFHHHHHHHHHHHHHHHGHGFHAFDHGHFHFHHGHGHHFHGFFGGHHHHHFGHFHB=0D::GCGHBHHFBCGGGGG~@M03235:53:000000000-AHLTD:1:1113:23312:4764  2:N:0:6~TCGTAGTAGTATTTCCTAAAATAAGGCAAACCATAGATGATAGACCCACAAAAAGAAAGTAAGATTAGGGTAAAAAAATTCCTTCTTAAAGTTTTTTCAGCATTTTTCACGACTTTCCTTTAAACATTTTGCTTACATTTTTGCATATTTTAGAAAATGCTTTTGATATTTAAGAGCTTGTAGGGCTTAAATTAAAAATTTTGTAGCTTATTTACACAATCTCACCTCATCTTGCAAACTTGGAACACTT~+~CCCCDCCFFFFFGGGGGGGGGGHHHHHHHHHGHHHHHHHHHHGHHHGHGGGHHHGGGHHHHFFHHFHHHFEGGHHHGGHHFHHHHHHHGHHFDGHGGFHHHHHHHHHHGHHGGGGGHHGGHHGHHHHHHHHHGHHHHHHHHHGGHHHHHHHHHHHHGHFFHHHHHGHGHHHFHFHHFHHHHHFBFFHHHEDHHHGFHHHHGHGHHDHBGGHHGHHFDGEHHHFFHHFHGHHHHGFC::CBFFBBFF/CFB
     TATCAAGGCTGCTCAAATGAT   35      @M03235:53:000000000-AHLTD:1:1114:18962:2371  1:N:0:6~TATCAAGGCTGCTCAAATGATGGCTTTTGTTATGCTCCGCAAAAGCGTGAATTTAGAATTTTTAAAGAGGGTCAAATTTATAAAACTAGCCCTTATGAAACAATGCAAAGTGAAGAAGAGCAAATCGCCTTTTCTTTGAAAAATGAAAATTTAGCACTCATCTTGCTTAGTTTTTTTGGTTACGGACTTTTGCTTTCTCTTACGCCTTGCACCTTACCGATGATTCCTATTTTATCTTCACTTATCATAG~+~AABBA5FBAFFBGGGGGGGGGGHGHHHFHHHHHHHHHCGGGGGBHFFEE2FHHFHHHFGGHHHGHHHFHGGGHGHHHHGHHHHHHHHHHHHFHHHGHHHHFFHHHHHHHHHHGHHHCGGGH3FHEGDAFGGGGHHFGHFHHEHHHGHFFFHHGEHHHHGHHHFHFFHHHHDFHHGCFDGHEHFEGDCCHHHBBG0GFHFHHBGGF-G?BGGGCGCG//;.9.CBFB0BBGGGGBFFFF0;0FFGFGBF00~@M03235:53:000000000-AHLTD:1:1114:18962:2371   2:N:0:6~GATTAAAGAAAGTAAAAAGCTTTGTTTTTTAGAAGGTTTCGTGCCACCTTTTGCTATGATAAGTGAAGATAAAATAGGAATCATCGGTAAGGTGCAAGGCGTAAGAGAAAGCAAAAGTCCGTAACCAAAAAAACTAAGCAAGATGAGTGCTAAATTTTCATTTTTCAAAGAAAAGGCGATTTGCTCTTCTTCACTTTGCATTGTTTCATAAGGGCTAGTTTTATAAATTTGACCCTCTTTAAAAATTCTAA~+~CCCCCFFFFFFFGGGGGGGGGGHHFHHHGGHHGGHHGHHHGHGGHHHGHHHHHHHHHHHHGHHHHHHHHHHHHHHHHHHHHHHHHHGGGEGFGFHHFHGHGGGEHGHHHHHHGHHHHFHFE?GEGHHHHGGGGGGGHHHHGHHHHHHHFDFHHHHGFHFHHGHHGHHHHHHHHHH.A@EGGC0D0G0D0GDHFHHFCC00FGFHHHHHHHFHB;EFGGFGGBFGEFGGFFFFGCBFGGGGGGBFGGFGFFF
    -

    Usage

    Usage: fasten_kmer [-h] [-n INT] [-p] [-v] [-k INT]
    +

    §Usage

    Usage: fasten_kmer [-h] [-n INT] [-p] [-v] [-k INT]
     Options:
        -h, --help          Print this help menu.
        -n, --numcpus INT   Number of CPUs (default: 1)
    @@ -25,6 +27,6 @@ 

    Examples

    -m, --remember-reads Add reads to subsequent columns. Each read begins with the kmer. Only lists reads in the forward direction. -

    Constants

    • Glues together paired end reads internally and is a -character not expected in any read

    Functions

    • Read fastq from stdin and count kmers
    • Read a str of nucleotides and count kmers. +

    Constants§

    • Glues together paired end reads internally and is a +character not expected in any read

    Functions§

    • Read fastq from stdin and count kmers
    • Read a str of nucleotides and count kmers. If should_revcomp is true, then will also count kmers on the opposite strand.
    • main 🔒
    • revcomp 🔒
      reverse-complement a dna sequence
    • Complementary nucleotide for ACTGUN, case insensitive
    \ No newline at end of file diff --git a/docs/fasten_metrics/all.html b/docs/fasten_metrics/all.html index 4862bbd6..7ae36233 100644 --- a/docs/fasten_metrics/all.html +++ b/docs/fasten_metrics/all.html @@ -1 +1,2 @@ -List of all items in this crate

    List of all items

    Functions

    \ No newline at end of file +List of all items in this crate +

    List of all items

    Functions

    \ No newline at end of file diff --git a/docs/fasten_metrics/fn.average_quality.html b/docs/fasten_metrics/fn.average_quality.html index 4c5f9e8b..9f8b933f 100644 --- a/docs/fasten_metrics/fn.average_quality.html +++ b/docs/fasten_metrics/fn.average_quality.html @@ -1,2 +1,3 @@ -average_quality in fasten_metrics - Rust
    pub(crate) fn average_quality(qual_line: &str) -> f32
    Expand description

    given a cigar line for quality, return its average

    +average_quality in fasten_metrics - Rust +
    pub(crate) fn average_quality(qual_line: &str) -> f32
    Expand description

    given a cigar line for quality, return its average

    \ No newline at end of file diff --git a/docs/fasten_metrics/fn.main.html b/docs/fasten_metrics/fn.main.html index c9571769..3692a346 100644 --- a/docs/fasten_metrics/fn.main.html +++ b/docs/fasten_metrics/fn.main.html @@ -1 +1,2 @@ -main in fasten_metrics - Rust

    Function fasten_metrics::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_metrics - Rust +

    Function fasten_metrics::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_metrics/fn.standard_deviation.html b/docs/fasten_metrics/fn.standard_deviation.html index 935badae..c4e9916c 100644 --- a/docs/fasten_metrics/fn.standard_deviation.html +++ b/docs/fasten_metrics/fn.standard_deviation.html @@ -1,2 +1,3 @@ -standard_deviation in fasten_metrics - Rust
    pub(crate) fn standard_deviation(vec: &Vec<f32>) -> f32
    Expand description

    Local implementation of standard deviation

    +standard_deviation in fasten_metrics - Rust +
    pub(crate) fn standard_deviation(vec: &Vec<f32>) -> f32
    Expand description

    Local implementation of standard deviation

    \ No newline at end of file diff --git a/docs/fasten_metrics/index.html b/docs/fasten_metrics/index.html index b97f72d8..acd975dd 100644 --- a/docs/fasten_metrics/index.html +++ b/docs/fasten_metrics/index.html @@ -1,7 +1,9 @@ -fasten_metrics - Rust

    Crate fasten_metrics

    source ·
    Expand description

    Gives read metrics on a read set. +fasten_metrics - Rust

    +

    Crate fasten_metrics

    source ·
    Expand description

    Gives read metrics on a read set. Values are given in a column delimited stdout.

    -

    Examples

    cat testdata/four_reads.fastq | fasten_metrics | column -t
    -

    Usage

    Usage: fasten_metrics [-h] [-n INT] [-p] [-v] [--each-read] [--distribution STRING]
    +

    §Examples

    cat testdata/four_reads.fastq | fasten_metrics | column -t
    +

    §Usage

    Usage: fasten_metrics [-h] [-n INT] [-p] [-v] [--each-read] [--distribution STRING]
     Options:
        -h, --help          Print this help menu.
        -n, --numcpus INT   Number of CPUs (default: 1)
    @@ -12,4 +14,4 @@ 

    Examples

    Functions

    \ No newline at end of file +

    Functions§

    \ No newline at end of file diff --git a/docs/fasten_mutate/all.html b/docs/fasten_mutate/all.html index 16623ac9..f704e47b 100644 --- a/docs/fasten_mutate/all.html +++ b/docs/fasten_mutate/all.html @@ -1 +1,2 @@ -List of all items in this crate

    List of all items

    Functions

    \ No newline at end of file +List of all items in this crate +

    List of all items

    Functions

    \ No newline at end of file diff --git a/docs/fasten_mutate/fn.main.html b/docs/fasten_mutate/fn.main.html index 588895e0..ece3448c 100644 --- a/docs/fasten_mutate/fn.main.html +++ b/docs/fasten_mutate/fn.main.html @@ -1 +1,2 @@ -main in fasten_mutate - Rust

    Function fasten_mutate::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_mutate - Rust +

    Function fasten_mutate::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_mutate/fn.mutate.html b/docs/fasten_mutate/fn.mutate.html index 2599c728..8652f7ef 100644 --- a/docs/fasten_mutate/fn.mutate.html +++ b/docs/fasten_mutate/fn.mutate.html @@ -1,9 +1,10 @@ -mutate in fasten_mutate - Rust

    Function fasten_mutate::mutate

    source ·
    pub(crate) fn mutate(
    -    seq: &str,
    -    nts: &Vec<char>,
    -    num_snps: u8,
    -    mark: bool
    -) -> String
    Expand description

    Mutate a str of a sequence of nucleotides using the nucleotides +mutate in fasten_mutate - Rust

    +

    Function fasten_mutate::mutate

    source ·
    pub(crate) fn mutate(
    +    seq: &str,
    +    nts: &Vec<char>,
    +    num_snps: u8,
    +    mark: bool
    +) -> String
    Expand description

    Mutate a str of a sequence of nucleotides using the nucleotides in a vector nts. This function does not use any kind of mutation model and will choose random positions to replace with random nucleotides.

    diff --git a/docs/fasten_mutate/index.html b/docs/fasten_mutate/index.html index b4942efb..f9c61e26 100644 --- a/docs/fasten_mutate/index.html +++ b/docs/fasten_mutate/index.html @@ -1,6 +1,8 @@ -fasten_mutate - Rust

    Crate fasten_mutate

    source ·
    Expand description

    Mutates reads. There is no mutation model; only randomness.

    -

    Examples

    cat testdata/four_reads.fastq | fasten_mutate > out.fastq
    -

    Usage

     
    +fasten_mutate - Rust
    +    

    Crate fasten_mutate

    source ·
    Expand description

    Mutates reads. There is no mutation model; only randomness.

    +

    §Examples

    cat testdata/four_reads.fastq | fasten_mutate > out.fastq
    +

    §Usage

     
     fasten_mutate: Introduces point mutations randomly. There is no
     evolutionary model; multiple hits are allowed. Therefore,
     the number of SNPs through --snps is an upper
    @@ -19,7 +21,7 @@ 

    Examples

    Functions

    • main 🔒
    • mutate 🔒
      Mutate a str of a sequence of nucleotides using the nucleotides +

    Functions§

    • main 🔒
    • mutate 🔒
      Mutate a str of a sequence of nucleotides using the nucleotides in a vector nts. This function does not use any kind of mutation model and will choose random positions to replace with random nucleotides.
    \ No newline at end of file diff --git a/docs/fasten_normalize/all.html b/docs/fasten_normalize/all.html index 4add8fac..4ef196f1 100644 --- a/docs/fasten_normalize/all.html +++ b/docs/fasten_normalize/all.html @@ -1 +1,2 @@ -List of all items in this crate

    List of all items

    Functions

    Constants

    \ No newline at end of file +List of all items in this crate +

    List of all items

    Functions

    Constants

    \ No newline at end of file diff --git a/docs/fasten_normalize/constant.READ_SEPARATOR.html b/docs/fasten_normalize/constant.READ_SEPARATOR.html index 4ce12de0..d89936d6 100644 --- a/docs/fasten_normalize/constant.READ_SEPARATOR.html +++ b/docs/fasten_normalize/constant.READ_SEPARATOR.html @@ -1,3 +1,4 @@ -READ_SEPARATOR in fasten_normalize - Rust
    pub(crate) const READ_SEPARATOR: char = '~';
    Expand description

    Glues together paired end reads internally and is a +READ_SEPARATOR in fasten_normalize - Rust

    +
    pub(crate) const READ_SEPARATOR: char = '~';
    Expand description

    Glues together paired end reads internally and is a character not expected in any read

    \ No newline at end of file diff --git a/docs/fasten_normalize/fn.main.html b/docs/fasten_normalize/fn.main.html index c88c8b43..b4afaacc 100644 --- a/docs/fasten_normalize/fn.main.html +++ b/docs/fasten_normalize/fn.main.html @@ -1 +1,2 @@ -main in fasten_normalize - Rust

    Function fasten_normalize::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_normalize - Rust +

    Function fasten_normalize::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_normalize/fn.normalize_coverage.html b/docs/fasten_normalize/fn.normalize_coverage.html index 9b1ce3c6..32404a6e 100644 --- a/docs/fasten_normalize/fn.normalize_coverage.html +++ b/docs/fasten_normalize/fn.normalize_coverage.html @@ -1,6 +1,7 @@ -normalize_coverage in fasten_normalize - Rust
    pub(crate) fn normalize_coverage(
    -    stdin: Stdin,
    -    target_depth: u32,
    -    paired_end: bool
    +normalize_coverage in fasten_normalize - Rust
    +    
    pub(crate) fn normalize_coverage(
    +    stdin: Stdin,
    +    target_depth: u32,
    +    paired_end: bool
     )
    Expand description

    Normalize the coverage to a certain target and print as a fastq

    \ No newline at end of file diff --git a/docs/fasten_normalize/fn.print_reads.html b/docs/fasten_normalize/fn.print_reads.html index 29bab47c..f6abb7c4 100644 --- a/docs/fasten_normalize/fn.print_reads.html +++ b/docs/fasten_normalize/fn.print_reads.html @@ -1,2 +1,3 @@ -print_reads in fasten_normalize - Rust
    pub(crate) fn print_reads(reads: Vec<&str>)
    Expand description

    Print the reads in fastq format when given in a single line with ~

    +print_reads in fasten_normalize - Rust +
    pub(crate) fn print_reads(reads: Vec<&str>)
    Expand description

    Print the reads in fastq format when given in a single line with READ_SEPARATOR

    \ No newline at end of file diff --git a/docs/fasten_normalize/index.html b/docs/fasten_normalize/index.html index d4ef8aae..bdae3c48 100644 --- a/docs/fasten_normalize/index.html +++ b/docs/fasten_normalize/index.html @@ -1,9 +1,11 @@ -fasten_normalize - Rust

    Crate fasten_normalize

    source ·
    Expand description

    Normalizes kmer depth by removing some reads from high kmer depths +fasten_normalize - Rust

    +

    Crate fasten_normalize

    source ·
    Expand description

    Normalizes kmer depth by removing some reads from high kmer depths The input has to be from fasten_kmer --remember-reads where there are at least three columns: kmer, count, read1, [read2,…]

    This was inspired by BBNorm and is probably not the exact same algorithm. https://jgi.doe.gov/data-and-tools/software-tools/bbtools/bb-tools-user-guide/bbnorm-guide/

    -

    Examples

    cat testdata/four_reads.fastq | \
    +

    §Examples

    cat testdata/four_reads.fastq | \
       fasten_kmer -k 5 --remember-reads | \
       fasten_normalize | \
       gzip -c > four_reads.normalized.fastq.gz
    @@ -14,7 +16,7 @@ 

    Examples

    Usage

    Usage: fasten_normalize [-h] [-n INT] [-p] [--verbose] [--version] [-t INT]
    +

    §Usage

    Usage: fasten_normalize [-h] [-n INT] [-p] [--verbose] [--version] [-t INT]
     
     Options:
         -h, --help          Print this help menu.
    @@ -24,7 +26,7 @@ 

    Examples

    Algorithm

    +

    §Algorithm

    fasten_normalize will downsample reads pertaining to each kmer. For example, if AAAA is found in the fasten_kmer output 100 times, but you request 10x coverage, it will remove 90% of the @@ -38,10 +40,10 @@

    Examples

    fasten_normalize randomly selects reads that begin with that kmer and brings the number of reads down to that target coverage. -

    Choosing the correct k

    +

    §Choosing the correct k

    Choose a kmer length that is unique enough in the genome but that will not be long enough to run into read-level errors. In the examples above, k=3 is likely very short. Starting with something like k=31 is probably a good start.

    -

    Constants

    • Glues together paired end reads internally and is a -character not expected in any read

    Functions

    • main 🔒
    • Normalize the coverage to a certain target and print as a fastq
    • Print the reads in fastq format when given in a single line with ~
    \ No newline at end of file +

    Constants§

    • Glues together paired end reads internally and is a +character not expected in any read

    Functions§

    • main 🔒
    • Normalize the coverage to a certain target and print as a fastq
    • Print the reads in fastq format when given in a single line with READ_SEPARATOR
    \ No newline at end of file diff --git a/docs/fasten_pe/all.html b/docs/fasten_pe/all.html index 44bc090d..b49505a5 100644 --- a/docs/fasten_pe/all.html +++ b/docs/fasten_pe/all.html @@ -1 +1,2 @@ -List of all items in this crate
    \ No newline at end of file +List of all items in this crate +
    \ No newline at end of file diff --git a/docs/fasten_pe/fn.is_paired_end_miseq.html b/docs/fasten_pe/fn.is_paired_end_miseq.html index 4f4f23a4..39a4d835 100644 --- a/docs/fasten_pe/fn.is_paired_end_miseq.html +++ b/docs/fasten_pe/fn.is_paired_end_miseq.html @@ -1,7 +1,8 @@ -is_paired_end_miseq in fasten_pe - Rust
    pub(crate) fn is_paired_end_miseq(
    -    id1_ref: &Vec<String>,
    -    id2_ref: &Vec<String>
    -) -> u8
    Expand description

    Detect whether the vector of IDs represent paired-endedness +is_paired_end_miseq in fasten_pe - Rust

    +
    pub(crate) fn is_paired_end_miseq(
    +    id1_ref: &Vec<String>,
    +    id2_ref: &Vec<String>
    +) -> u8
    Expand description

    Detect whether the vector of IDs represent paired-endedness with finding out whether they fit the pattern shown in Illumina documentation at http://support.illumina.com/content/dam/illumina-support/help/BaseSpaceHelp_v2/Content/Vault/Informatics/Sequencing_Analysis/BS/swSEQ_mBS_FASTQFiles.htm

    \ No newline at end of file diff --git a/docs/fasten_pe/fn.is_paired_end_slash12.html b/docs/fasten_pe/fn.is_paired_end_slash12.html index d1785378..7d0429c1 100644 --- a/docs/fasten_pe/fn.is_paired_end_slash12.html +++ b/docs/fasten_pe/fn.is_paired_end_slash12.html @@ -1,6 +1,7 @@ -is_paired_end_slash12 in fasten_pe - Rust
    pub(crate) fn is_paired_end_slash12(
    -    id1_ref: &Vec<String>,
    -    id2_ref: &Vec<String>
    -) -> u8
    Expand description

    Detect whether the vector of IDs represent paired-endedness +is_paired_end_slash12 in fasten_pe - Rust

    +
    pub(crate) fn is_paired_end_slash12(
    +    id1_ref: &Vec<String>,
    +    id2_ref: &Vec<String>
    +) -> u8
    Expand description

    Detect whether the vector of IDs represent paired-endedness with finding out whether they end with /1 and /2.

    \ No newline at end of file diff --git a/docs/fasten_pe/fn.main.html b/docs/fasten_pe/fn.main.html index be377cd7..1b72f88d 100644 --- a/docs/fasten_pe/fn.main.html +++ b/docs/fasten_pe/fn.main.html @@ -1 +1,2 @@ -main in fasten_pe - Rust

    Function fasten_pe::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_pe - Rust +

    Function fasten_pe::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_pe/index.html b/docs/fasten_pe/index.html index b2e4e1b8..7dd540b2 100644 --- a/docs/fasten_pe/index.html +++ b/docs/fasten_pe/index.html @@ -1,8 +1,10 @@ -fasten_pe - Rust

    Crate fasten_pe

    source ·
    Expand description

    Determine paired-end-ness in an interleaved file. +fasten_pe - Rust

    +

    Crate fasten_pe

    source ·
    Expand description

    Determine paired-end-ness in an interleaved file. Exit code of 0 indicates PE. Exit code > 0 indicates single end.

    -

    Examples

    Test the file and then print a message with the exit code

    cat file.fastq | fasten_pe; echo "Reads were paired-end? $?";
    -

    Test the file and if it is paired end (exit code 0), then print a message

    cat file.fastq | fasten_pe || echo "Reads were paired end.";
    -

    Usage

    Usage: fasten_pe [-h] [-n INT] [-p] [-v] [--print-reads]
    +

    §Examples

    §Test the file and then print a message with the exit code

    cat file.fastq | fasten_pe; echo "Reads were paired-end? $?";
    +

    §Test the file and if it is paired end (exit code 0), then print a message

    cat file.fastq | fasten_pe || echo "Reads were paired end.";
    +

    §Usage

    Usage: fasten_pe [-h] [-n INT] [-p] [-v] [--print-reads]
      
     Options:
         -h, --help          Print this help menu.
    @@ -10,7 +12,7 @@ 

    Examples

    Functions

    Functions§

    \ No newline at end of file diff --git a/docs/fasten_progress/all.html b/docs/fasten_progress/all.html index ba83393c..932e3049 100644 --- a/docs/fasten_progress/all.html +++ b/docs/fasten_progress/all.html @@ -1 +1,2 @@ -List of all items in this crate

    List of all items

    Functions

    \ No newline at end of file +List of all items in this crate +

    List of all items

    Functions

    \ No newline at end of file diff --git a/docs/fasten_progress/fn.main.html b/docs/fasten_progress/fn.main.html index 3950635d..e09dff13 100644 --- a/docs/fasten_progress/fn.main.html +++ b/docs/fasten_progress/fn.main.html @@ -1 +1,2 @@ -main in fasten_progress - Rust

    Function fasten_progress::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_progress - Rust +

    Function fasten_progress::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_progress/index.html b/docs/fasten_progress/index.html index ee549799..991b3690 100644 --- a/docs/fasten_progress/index.html +++ b/docs/fasten_progress/index.html @@ -1,12 +1,14 @@ -fasten_progress - Rust

    Crate fasten_progress

    source ·
    Expand description

    Prints a progress meter for number of fastq entries to stderr.

    -

    Examples

    fasten_metrics progress

    +fasten_progress - Rust +

    Crate fasten_progress

    source ·
    Expand description

    Prints a progress meter for number of fastq entries to stderr.

    +

    §Examples

    §fasten_metrics progress

    While getting read metrics for a large fastq file, print the progress to make the wait a little easier

    cat large.fastq | fasten_progress --print | fasten_metrics
    -

    fasten_shuffle progress

    +

    §fasten_shuffle progress

    While shuffling a large fastq file, print the progress

    cat large_1.fastq large_2.fastq | fasten_progress --print | fasten_shuffle > interleaved.fastq
    -

    Two progress bars

    +

    §Two progress bars

    When there is a halting step in the process like fasten_sort, then it might make sense to have two progress bars. However, if there are no halting steps then the progress messages will collide.

    @@ -17,7 +19,7 @@

    Examples

    Usage

    Usage: fasten_progress [-h] [-n INT] [-p] [-v] [--id STRING] [--update-every INT]
    +

    §Usage

    Usage: fasten_progress [-h] [-n INT] [-p] [-v] [--id STRING] [--update-every INT]
      
     Options:
         -h, --help          Print this help menu.
    @@ -28,4 +30,4 @@ 

    Examples

    Functions

    \ No newline at end of file +

    Functions§

    \ No newline at end of file diff --git a/docs/fasten_quality_filter/all.html b/docs/fasten_quality_filter/all.html index 8021ef6d..efde6b20 100644 --- a/docs/fasten_quality_filter/all.html +++ b/docs/fasten_quality_filter/all.html @@ -1 +1,2 @@ -List of all items in this crate

    List of all items

    Functions

    \ No newline at end of file +List of all items in this crate +

    List of all items

    Functions

    \ No newline at end of file diff --git a/docs/fasten_quality_filter/fn.main.html b/docs/fasten_quality_filter/fn.main.html index e4edc31b..926ad150 100644 --- a/docs/fasten_quality_filter/fn.main.html +++ b/docs/fasten_quality_filter/fn.main.html @@ -1 +1,2 @@ -main in fasten_quality_filter - Rust
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_quality_filter - Rust +
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_quality_filter/index.html b/docs/fasten_quality_filter/index.html index be0fae3e..4bcf0921 100644 --- a/docs/fasten_quality_filter/index.html +++ b/docs/fasten_quality_filter/index.html @@ -1,6 +1,8 @@ -fasten_quality_filter - Rust
    Expand description

    Transforms any low-quality base to ‘N’

    -

    Examples

    cat file.fastq | fasten_quality_filter > file_with_Ns.fastq
    -

    Usage

     
    +fasten_quality_filter - Rust
    +    
    Expand description

    Transforms any low-quality base to ‘N’

    +

    §Examples

    cat file.fastq | fasten_quality_filter > file_with_Ns.fastq
    +

    §Usage

     
     Usage: fasten_quality_filter [-h] [-n INT] [-p] [-v] [-m INT]
      
     Options:
    @@ -11,4 +13,4 @@ 

    Examples

    Functions

    \ No newline at end of file +

    Functions§

    \ No newline at end of file diff --git a/docs/fasten_randomize/all.html b/docs/fasten_randomize/all.html index 791a17b4..26dcd26a 100644 --- a/docs/fasten_randomize/all.html +++ b/docs/fasten_randomize/all.html @@ -1 +1,2 @@ -List of all items in this crate

    List of all items

    Functions

    \ No newline at end of file +List of all items in this crate +

    List of all items

    Functions

    \ No newline at end of file diff --git a/docs/fasten_randomize/fn.main.html b/docs/fasten_randomize/fn.main.html index f7bcb841..30038a6a 100644 --- a/docs/fasten_randomize/fn.main.html +++ b/docs/fasten_randomize/fn.main.html @@ -1 +1,2 @@ -main in fasten_randomize - Rust

    Function fasten_randomize::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_randomize - Rust +

    Function fasten_randomize::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_randomize/fn.print_reads_from_stdin.html b/docs/fasten_randomize/fn.print_reads_from_stdin.html index f10bab4a..d7ef6a85 100644 --- a/docs/fasten_randomize/fn.print_reads_from_stdin.html +++ b/docs/fasten_randomize/fn.print_reads_from_stdin.html @@ -1,3 +1,4 @@ -print_reads_from_stdin in fasten_randomize - Rust
    pub(crate) fn print_reads_from_stdin(lines_per_read: u32)
    Expand description

    Read fastq from stdin, add the reads to a vector, +print_reads_from_stdin in fasten_randomize - Rust

    +
    pub(crate) fn print_reads_from_stdin(lines_per_read: u32)
    Expand description

    Read fastq from stdin, add the reads to a vector, then print them to stdout in random order

    \ No newline at end of file diff --git a/docs/fasten_randomize/index.html b/docs/fasten_randomize/index.html index c1691e7e..54cbc1bb 100644 --- a/docs/fasten_randomize/index.html +++ b/docs/fasten_randomize/index.html @@ -1,20 +1,22 @@ -fasten_randomize - Rust

    Crate fasten_randomize

    source ·
    Expand description

    Create random reads from stdin.

    -

    Examples

    print "hello world\n";
    -

    General usage

    +fasten_randomize - Rust +

    Crate fasten_randomize

    source ·
    Expand description

    Create random reads from stdin.

    +

    §Examples

    print "hello world\n";
    +

    §General usage

    General usage to randomize the order of the reads

    cat file.fastq | fasten_randomize > random.fastq
    -

    One read

    +

    §One read

    Get one random read. Entries will always be in a 4-line format.

    cat file.fastq | fasten_randomize | head -n 4 > one_read.fastq
    -

    Paired end

    +

    §Paired end

    If paired, keep them together

    cat R1.fastq R2.fastq | fasten_shuffle | fasten_randomize --paired-end | head -n 8 > one_pair.fastq
    -

    Usage

    Usage: fasten_randomize [-h] [-n INT] [-p] [-v]
    +

    §Usage

    Usage: fasten_randomize [-h] [-n INT] [-p] [-v]
      
     Options:
         -h, --help          Print this help menu.
         -n, --numcpus INT   Number of CPUs (default: 1)
         -p, --paired-end    The input reads are interleaved paired-end
         -v, --verbose       Print more status messages
    -

    Functions

    Functions§

    • main 🔒
    • Read fastq from stdin, add the reads to a vector, then print them to stdout in random order
    \ No newline at end of file diff --git a/docs/fasten_regex/all.html b/docs/fasten_regex/all.html index 38242342..f173b446 100644 --- a/docs/fasten_regex/all.html +++ b/docs/fasten_regex/all.html @@ -1 +1,2 @@ -List of all items in this crate

    List of all items

    Functions

    \ No newline at end of file +List of all items in this crate +

    List of all items

    Functions

    \ No newline at end of file diff --git a/docs/fasten_regex/fn.main.html b/docs/fasten_regex/fn.main.html index 6cc0cb33..0c7dd6d8 100644 --- a/docs/fasten_regex/fn.main.html +++ b/docs/fasten_regex/fn.main.html @@ -1 +1,2 @@ -main in fasten_regex - Rust

    Function fasten_regex::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_regex - Rust +

    Function fasten_regex::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_regex/index.html b/docs/fasten_regex/index.html index 36be83d6..9d631e4c 100644 --- a/docs/fasten_regex/index.html +++ b/docs/fasten_regex/index.html @@ -1,8 +1,10 @@ -fasten_regex - Rust

    Crate fasten_regex

    source ·
    Expand description

    Filter reads based on a regular expression.

    -

    Examples

    Find a specific read

    cat file.fastq | fasten_regex --which ID --regex 'my-specific-read-id-1234' > my_read.fastq
    -

    Find a specific read but also keep its pair

    cat file.fastq | fasten_regex --which ID --regex 'my-specific-read-id-1234' --paired-end > my_pairs.fastq
    -

    Find a specific motif

    cat file.fastq | fasten_regex --which SEQ --regex ATAT > atat-motif.fastq
    -

    Usage

    Usage: fasten_regex [-h] [-n INT] [-p] [-v] [-r STRING] [-w String]
    +fasten_regex - Rust
    +    

    Crate fasten_regex

    source ·
    Expand description

    Filter reads based on a regular expression.

    +

    §Examples

    §Find a specific read

    cat file.fastq | fasten_regex --which ID --regex 'my-specific-read-id-1234' > my_read.fastq
    +

    §Find a specific read but also keep its pair

    cat file.fastq | fasten_regex --which ID --regex 'my-specific-read-id-1234' --paired-end > my_pairs.fastq
    +

    §Find a specific motif

    cat file.fastq | fasten_regex --which SEQ --regex ATAT > atat-motif.fastq
    +

    §Usage

    Usage: fasten_regex [-h] [-n INT] [-p] [-v] [-r STRING] [-w String]
      
     Options:
         -h, --help          Print this help menu.
    @@ -11,4 +13,4 @@ 

    Examples

    Functions

    \ No newline at end of file +

    Functions§

    \ No newline at end of file diff --git a/docs/fasten_repair/all.html b/docs/fasten_repair/all.html index 26678ba7..7f47c3ab 100644 --- a/docs/fasten_repair/all.html +++ b/docs/fasten_repair/all.html @@ -1 +1,2 @@ -List of all items in this crate

    List of all items

    Functions

    \ No newline at end of file +List of all items in this crate +

    List of all items

    Functions

    \ No newline at end of file diff --git a/docs/fasten_repair/fn.main.html b/docs/fasten_repair/fn.main.html index 9afbd2cd..da2fa2d2 100644 --- a/docs/fasten_repair/fn.main.html +++ b/docs/fasten_repair/fn.main.html @@ -1 +1,2 @@ -main in fasten_repair - Rust

    Function fasten_repair::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_repair - Rust +

    Function fasten_repair::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_repair/fn.repair_one_read.html b/docs/fasten_repair/fn.repair_one_read.html index 1b1b424a..96a73d09 100644 --- a/docs/fasten_repair/fn.repair_one_read.html +++ b/docs/fasten_repair/fn.repair_one_read.html @@ -1,11 +1,12 @@ -repair_one_read in fasten_repair - Rust
    pub(crate) fn repair_one_read(
    -    id: String,
    -    seq: String,
    -    plus: String,
    -    qual: String,
    -    should_repair: bool,
    -    min_length: usize,
    -    min_qual: f32,
    -    remove_info: bool
    -) -> (String, bool, String)
    Expand description

    Repair exactly one read

    +repair_one_read in fasten_repair - Rust +
    pub(crate) fn repair_one_read(
    +    id: String,
    +    seq: String,
    +    plus: String,
    +    qual: String,
    +    should_repair: bool,
    +    min_length: usize,
    +    min_qual: f32,
    +    remove_info: bool
    +) -> (String, bool, String)
    Expand description

    Repair exactly one read

    \ No newline at end of file diff --git a/docs/fasten_repair/fn.repair_reads.html b/docs/fasten_repair/fn.repair_reads.html index 85c71cf7..b0fb8608 100644 --- a/docs/fasten_repair/fn.repair_reads.html +++ b/docs/fasten_repair/fn.repair_reads.html @@ -1,8 +1,9 @@ -repair_reads in fasten_repair - Rust
    pub(crate) fn repair_reads(
    -    paired_end: bool,
    -    min_length: usize,
    -    min_qual: f32,
    -    remove_info: bool,
    -    mode: &str
    +repair_reads in fasten_repair - Rust
    +    
    pub(crate) fn repair_reads(
    +    paired_end: bool,
    +    min_length: usize,
    +    min_qual: f32,
    +    remove_info: bool,
    +    mode: &str
     )
    Expand description

    Repairs reads depending on the deflines by calling repair_one_read

    \ No newline at end of file diff --git a/docs/fasten_repair/index.html b/docs/fasten_repair/index.html index 06ea98ae..d1b17513 100644 --- a/docs/fasten_repair/index.html +++ b/docs/fasten_repair/index.html @@ -1,10 +1,12 @@ -fasten_repair - Rust

    Crate fasten_repair

    source ·
    Expand description

    Repairs reads from fasten_inspect output

    -

    Examples

    ./target/debug/fasten_inspect  < testdata/four_reads.fastq | \
    +fasten_repair - Rust
    +    

    Crate fasten_repair

    source ·
    Expand description

    Repairs reads from fasten_inspect output

    +

    §Examples

    ./target/debug/fasten_inspect  < testdata/four_reads.fastq | \
       ./target/debug/fasten_repair --remove-info > repaired.fastq
     
     

    If remove-info is given, then extra header information from fasten_inspect will be removed.

    -

    Usage

    Usage: fasten_repair [-h] [-n INT] [-p] [--verbose] [--version] [--min-length INT] [--min-quality FLOAT] [--remove-info] [-m STRING]
    +

    §Usage

    Usage: fasten_repair [-h] [-n INT] [-p] [--verbose] [--version] [--min-length INT] [--min-quality FLOAT] [--remove-info] [-m STRING]
     Options:
        -h, --help          Print this help menu.
        -n, --numcpus INT   Number of CPUs (default: 1)
    @@ -18,14 +20,14 @@ 

    Usage

    Methods of repair

    Repair mode

    +

    §Methods of repair

    §Repair mode

    If you choose --mode repair, then this is the expected behavior

    • Mismatched seq and qual lengths: seq or qual length will be truncated
    • R1 or R2 not passing: then the other (R1 or R2) will also not pass and they will not be printed.
    -

    Panic mode

    +

    §Panic mode

    • seq length < min length
    • avg qual < min qual
    • @@ -34,4 +36,4 @@

      Panic mode

    • @ not present in first character of the entry
    • + not present in the first character of the third line
    -

    Functions

    \ No newline at end of file +

    Functions§

    \ No newline at end of file diff --git a/docs/fasten_replace/all.html b/docs/fasten_replace/all.html index c8c2558e..81d1fb1f 100644 --- a/docs/fasten_replace/all.html +++ b/docs/fasten_replace/all.html @@ -1 +1,2 @@ -List of all items in this crate

    List of all items

    Functions

    \ No newline at end of file +List of all items in this crate +

    List of all items

    Functions

    \ No newline at end of file diff --git a/docs/fasten_replace/fn.main.html b/docs/fasten_replace/fn.main.html index 852069ea..ba30c5b6 100644 --- a/docs/fasten_replace/fn.main.html +++ b/docs/fasten_replace/fn.main.html @@ -1 +1,2 @@ -main in fasten_replace - Rust

    Function fasten_replace::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_replace - Rust +

    Function fasten_replace::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_replace/index.html b/docs/fasten_replace/index.html index 3d1e0ce9..eddf9dff 100644 --- a/docs/fasten_replace/index.html +++ b/docs/fasten_replace/index.html @@ -1,6 +1,8 @@ -fasten_replace - Rust

    Crate fasten_replace

    source ·
    Expand description

    Streaming editor for fastq data using a find/replace.

    -

    Examples

    Force a motif to be lowercase

    cat file.fastq | fasten_replace --which SEQ --find ATAT --replace atat > file.fastq
    -

    Mutate the middle base of a kmer

    cat file.fastq | fasten_replace --which SEQ --find AAAAA --replace AATAA > file.fastq
    +fasten_replace - Rust
    +    

    Crate fasten_replace

    source ·
    Expand description

    Streaming editor for fastq data using a find/replace.

    +

    §Examples

    §Force a motif to be lowercase

    cat file.fastq | fasten_replace --which SEQ --find ATAT --replace atat > file.fastq
    +

    §Mutate the middle base of a kmer

    cat file.fastq | fasten_replace --which SEQ --find AAAAA --replace AATAA > file.fastq
     
    # Usage
      
     Usage: fasten_replace [-h] [-n INT] [-p] [-v] [-f STRING] [-r STRING] [-w STRING]
    @@ -14,4 +16,4 @@ 

    Examples

    Functions

    \ No newline at end of file +

    Functions§

    \ No newline at end of file diff --git a/docs/fasten_sample/all.html b/docs/fasten_sample/all.html index 942e4353..2605d95b 100644 --- a/docs/fasten_sample/all.html +++ b/docs/fasten_sample/all.html @@ -1 +1,2 @@ -List of all items in this crate

    List of all items

    Functions

    \ No newline at end of file +List of all items in this crate +

    List of all items

    Functions

    \ No newline at end of file diff --git a/docs/fasten_sample/fn.main.html b/docs/fasten_sample/fn.main.html index 54ceb1f7..19c66c6e 100644 --- a/docs/fasten_sample/fn.main.html +++ b/docs/fasten_sample/fn.main.html @@ -1 +1,2 @@ -main in fasten_sample - Rust

    Function fasten_sample::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_sample - Rust +

    Function fasten_sample::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_sample/fn.rand_32.html b/docs/fasten_sample/fn.rand_32.html index 0a9d44d4..8555a202 100644 --- a/docs/fasten_sample/fn.rand_32.html +++ b/docs/fasten_sample/fn.rand_32.html @@ -1,2 +1,3 @@ -rand_32 in fasten_sample - Rust

    Function fasten_sample::rand_32

    source ·
    pub(crate) fn rand_32() -> Vec<f32>
    Expand description

    Generate a set of random floats

    +rand_32 in fasten_sample - Rust +

    Function fasten_sample::rand_32

    source ·
    pub(crate) fn rand_32() -> Vec<f32>
    Expand description

    Generate a set of random floats

    \ No newline at end of file diff --git a/docs/fasten_sample/index.html b/docs/fasten_sample/index.html index 637d6401..e6ad7df6 100644 --- a/docs/fasten_sample/index.html +++ b/docs/fasten_sample/index.html @@ -1,6 +1,8 @@ -fasten_sample - Rust

    Crate fasten_sample

    source ·
    Expand description

    downsample your reads

    -

    Examples

    Get 10% of the reads

    cat file.fastq | fasten_sample --frequency 0.1 > out.fastq
    -

    Usage

        Usage: fasten_sample [-h] [-n INT] [-p] [-v] [-f FLOAT]
    +fasten_sample - Rust
    +    

    Crate fasten_sample

    source ·
    Expand description

    downsample your reads

    +

    §Examples

    §Get 10% of the reads

    cat file.fastq | fasten_sample --frequency 0.1 > out.fastq
    +

    §Usage

        Usage: fasten_sample [-h] [-n INT] [-p] [-v] [-f FLOAT]
          
         Options:
             -h, --help          Print this help menu.
    @@ -9,4 +11,4 @@ 

    Examples

    Functions

    • main 🔒
    • rand_32 🔒
      Generate a set of random floats
    \ No newline at end of file +

    Functions§

    • main 🔒
    • rand_32 🔒
      Generate a set of random floats
    \ No newline at end of file diff --git a/docs/fasten_shuffle/all.html b/docs/fasten_shuffle/all.html index f364fe55..d6356f0b 100644 --- a/docs/fasten_shuffle/all.html +++ b/docs/fasten_shuffle/all.html @@ -1 +1,2 @@ -List of all items in this crate

    List of all items

    Functions

    \ No newline at end of file +List of all items in this crate +

    List of all items

    Functions

    \ No newline at end of file diff --git a/docs/fasten_shuffle/fn.deshuffle.html b/docs/fasten_shuffle/fn.deshuffle.html index 547f0b6e..3fffbb94 100644 --- a/docs/fasten_shuffle/fn.deshuffle.html +++ b/docs/fasten_shuffle/fn.deshuffle.html @@ -1,2 +1,3 @@ -deshuffle in fasten_shuffle - Rust

    Function fasten_shuffle::deshuffle

    source ·
    pub(crate) fn deshuffle(matches: &Matches)
    Expand description

    Read from stdin and deshuffle reads into files

    +deshuffle in fasten_shuffle - Rust +

    Function fasten_shuffle::deshuffle

    source ·
    pub(crate) fn deshuffle(matches: &Matches)
    Expand description

    Read from stdin and deshuffle reads into files

    \ No newline at end of file diff --git a/docs/fasten_shuffle/fn.main.html b/docs/fasten_shuffle/fn.main.html index e8e893da..baec1afd 100644 --- a/docs/fasten_shuffle/fn.main.html +++ b/docs/fasten_shuffle/fn.main.html @@ -1 +1,2 @@ -main in fasten_shuffle - Rust

    Function fasten_shuffle::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_shuffle - Rust +

    Function fasten_shuffle::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_shuffle/fn.read_seqs.html b/docs/fasten_shuffle/fn.read_seqs.html index b21a0bdf..dcba6092 100644 --- a/docs/fasten_shuffle/fn.read_seqs.html +++ b/docs/fasten_shuffle/fn.read_seqs.html @@ -1,2 +1,3 @@ -read_seqs in fasten_shuffle - Rust

    Function fasten_shuffle::read_seqs

    source ·
    pub(crate) fn read_seqs(filename: &String) -> Vec<Seq>
    Expand description

    Read fastq entries from a filename

    +read_seqs in fasten_shuffle - Rust +

    Function fasten_shuffle::read_seqs

    source ·
    pub(crate) fn read_seqs(filename: &String) -> Vec<Seq>
    Expand description

    Read fastq entries from a filename

    \ No newline at end of file diff --git a/docs/fasten_shuffle/fn.shuffle.html b/docs/fasten_shuffle/fn.shuffle.html index cc595d41..44ca3efa 100644 --- a/docs/fasten_shuffle/fn.shuffle.html +++ b/docs/fasten_shuffle/fn.shuffle.html @@ -1,2 +1,3 @@ -shuffle in fasten_shuffle - Rust

    Function fasten_shuffle::shuffle

    source ·
    pub(crate) fn shuffle(matches: &Matches)
    Expand description

    Read fastq from stdin and interleave

    +shuffle in fasten_shuffle - Rust +

    Function fasten_shuffle::shuffle

    source ·
    pub(crate) fn shuffle(matches: &Matches)
    Expand description

    Read fastq from stdin and interleave

    \ No newline at end of file diff --git a/docs/fasten_shuffle/index.html b/docs/fasten_shuffle/index.html index 15c8a2b5..df4f2f91 100644 --- a/docs/fasten_shuffle/index.html +++ b/docs/fasten_shuffle/index.html @@ -1,13 +1,15 @@ -fasten_shuffle - Rust

    Crate fasten_shuffle

    source ·
    Expand description

    Interleaves reads from either stdin or file parameters.

    +fasten_shuffle - Rust +

    Crate fasten_shuffle

    source ·
    Expand description

    Interleaves reads from either stdin or file parameters.

    Many fasten executables are aware of paired end reads but they need to be in interleaved format. This script transforms R1 and R2 reads into interleaved format.

    -

    Examples

    Shuffling

    Simple transformation of R1 and R2 into interleaved

    cat file_1.fastq file_2.fastq | fasten_shuffle > interleaved.fastq
    +

    §Examples

    §Shuffling

    §Simple transformation of R1 and R2 into interleaved

    cat file_1.fastq file_2.fastq | fasten_shuffle > interleaved.fastq
     fasten_shuffle -1 file_1.fastq -2 file_2.fastq > interleaved.fastq
    -

    interleave R1 and R2 and pipe it into another executable with –paired-end

    cat file_1.fastq file_2.fastq | fasten_randomize --paired-end | head -n 8 > random-pair.fastq
    -

    … or to another executable with –paired-end

    cat file_1.fastq file_2.fastq | fasten_sample --paired-end --frequency 0.2 > downsample.20percent.fastq
    -

    Deshuffling

    cat interleaved.fastq | fasten_shuffle -d -1 1.fastq -2 2.fastq
    -

    Usage

    Usage: fasten_shuffle [-h] [-n INT] [-p] [-v] [-d] [-1 1.fastq] [-2 2.fastq]
    +

    §interleave R1 and R2 and pipe it into another executable with –paired-end

    cat file_1.fastq file_2.fastq | fasten_randomize --paired-end | head -n 8 > random-pair.fastq
    +

    §… or to another executable with –paired-end

    cat file_1.fastq file_2.fastq | fasten_sample --paired-end --frequency 0.2 > downsample.20percent.fastq
    +

    §Deshuffling

    cat interleaved.fastq | fasten_shuffle -d -1 1.fastq -2 2.fastq
    +

    §Usage

    Usage: fasten_shuffle [-h] [-n INT] [-p] [-v] [-d] [-1 1.fastq] [-2 2.fastq]
      
     Options:
         -h, --help          Print this help menu.
    @@ -19,4 +21,4 @@ 

    Examples

    Functions

    • deshuffle 🔒
      Read from stdin and deshuffle reads into files
    • main 🔒
    • read_seqs 🔒
      Read fastq entries from a filename
    • shuffle 🔒
      Read fastq from stdin and interleave
    \ No newline at end of file +

    Functions§

    • deshuffle 🔒
      Read from stdin and deshuffle reads into files
    • main 🔒
    • read_seqs 🔒
      Read fastq entries from a filename
    • shuffle 🔒
      Read fastq from stdin and interleave
    \ No newline at end of file diff --git a/docs/fasten_sort/all.html b/docs/fasten_sort/all.html index d86911ae..b92feeb9 100644 --- a/docs/fasten_sort/all.html +++ b/docs/fasten_sort/all.html @@ -1 +1,2 @@ -List of all items in this crate

    List of all items

    Structs

    Functions

    \ No newline at end of file +List of all items in this crate +

    List of all items

    Structs

    Functions

    \ No newline at end of file diff --git a/docs/fasten_sort/fn.main.html b/docs/fasten_sort/fn.main.html index 49359afa..33362baf 100644 --- a/docs/fasten_sort/fn.main.html +++ b/docs/fasten_sort/fn.main.html @@ -1 +1,2 @@ -main in fasten_sort - Rust

    Function fasten_sort::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_sort - Rust +

    Function fasten_sort::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_sort/fn.sort_entries.html b/docs/fasten_sort/fn.sort_entries.html index fe598b80..edce3bda 100644 --- a/docs/fasten_sort/fn.sort_entries.html +++ b/docs/fasten_sort/fn.sort_entries.html @@ -1,6 +1,7 @@ -sort_entries in fasten_sort - Rust

    Function fasten_sort::sort_entries

    source ·
    pub(crate) fn sort_entries(
    -    unsorted: Vec<Seq>,
    -    which_field: &str,
    -    reverse_sort: bool
    -) -> Vec<Seq>
    Expand description

    Sort fastq entries in a vector

    +sort_entries in fasten_sort - Rust +

    Function fasten_sort::sort_entries

    source ·
    pub(crate) fn sort_entries(
    +    unsorted: Vec<Seq>,
    +    which_field: &str,
    +    reverse_sort: bool
    +) -> Vec<Seq>
    Expand description

    Sort fastq entries in a vector

    \ No newline at end of file diff --git a/docs/fasten_sort/index.html b/docs/fasten_sort/index.html index 84683d16..e7298397 100644 --- a/docs/fasten_sort/index.html +++ b/docs/fasten_sort/index.html @@ -1,12 +1,14 @@ -fasten_sort - Rust

    Crate fasten_sort

    source ·
    Expand description

    Sort a fastq file. +fasten_sort - Rust

    +

    Crate fasten_sort

    source ·
    Expand description

    Sort a fastq file. If the reads are paired end, then the sorted field concatenates R1 and R2 before comparisons in the sort. R1 and R2 reads will stay together if paired end.

    Sorting by GC content will give better compression by magic of gzip and other algorithms.

    Sorting can also aid in stable hashsums.

    -

    Examples

    stable hashsum

    cat file.fastq | fasten_sort | md5sum > file.fastq.md5
    -

    better compression by sorting by GC content

    zcat file.fastq.gz | fasten_sort --sort-by GC | gzip -c > smaller.fastq.gz
    +

    §Examples

    §stable hashsum

    cat file.fastq | fasten_sort | md5sum > file.fastq.md5
    +

    §better compression by sorting by GC content

    zcat file.fastq.gz | fasten_sort --sort-by GC | gzip -c > smaller.fastq.gz
      
     ## get good compression from paired end reads
     ```bash
    @@ -18,7 +20,7 @@ 

    Examples

    <

    Compare compression between unsorted and sorted from the previous example

    ls -lh sorted_1.fastq.gz sorted_2.fastq.gz
    -

    Usage

    Usage: fasten_sort [-h] [-n INT] [-p] [-v] [-s STRING] [-r]
    +

    §Usage

    Usage: fasten_sort [-h] [-n INT] [-p] [-v] [-s STRING] [-r]
     
     Options:
         -h, --help          Print this help menu.
    @@ -30,4 +32,4 @@ 

    Examples

    < are sorted by GC percentage. SEQ and ID are alphabetically sorted. -r, --reverse Reverse sort -

    Structs

    • Seq 🔒
      A sequence struct that is paired-end aware

    Functions

    \ No newline at end of file +

    Structs§

    • Seq 🔒
      A sequence struct that is paired-end aware

    Functions§

    \ No newline at end of file diff --git a/docs/fasten_sort/struct.Seq.html b/docs/fasten_sort/struct.Seq.html index d13dede1..816fd994 100644 --- a/docs/fasten_sort/struct.Seq.html +++ b/docs/fasten_sort/struct.Seq.html @@ -1,21 +1,22 @@ -Seq in fasten_sort - Rust

    Struct fasten_sort::Seq

    source ·
    pub(crate) struct Seq {
    -    pub(crate) pe: bool,
    -    pub(crate) id1: String,
    -    pub(crate) seq1: String,
    -    pub(crate) qual1: String,
    -    pub(crate) id2: String,
    -    pub(crate) seq2: String,
    -    pub(crate) qual2: String,
    +Seq in fasten_sort - Rust
    +    

    Struct fasten_sort::Seq

    source ·
    pub(crate) struct Seq {
    +    pub(crate) pe: bool,
    +    pub(crate) id1: String,
    +    pub(crate) seq1: String,
    +    pub(crate) qual1: String,
    +    pub(crate) id2: String,
    +    pub(crate) seq2: String,
    +    pub(crate) qual2: String,
     }
    Expand description

    A sequence struct that is paired-end aware

    -

    Fields§

    §pe: bool§id1: String§seq1: String§qual1: String§id2: String§seq2: String§qual2: String

    Trait Implementations§

    source§

    impl Clone for Seq

    source§

    fn clone(&self) -> Seq

    Returns a copy 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 Debug for Seq

    source§

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

    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    §

    impl RefUnwindSafe for Seq

    §

    impl Send for Seq

    §

    impl Sync for Seq

    §

    impl Unpin for Seq

    §

    impl UnwindSafe for Seq

    Blanket Implementations§

    source§

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

    source§

    fn type_id(&self) -> TypeId

    Gets the TypeId of self. Read more
    source§

    impl<T> Borrow<T> for Twhere - T: ?Sized,

    source§

    fn borrow(&self) -> &T

    Immutably borrows from an owned value. Read more
    source§

    impl<T> BorrowMut<T> for Twhere - T: ?Sized,

    source§

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

    Mutably borrows from an owned value. 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 Twhere - U: From<T>,

    source§

    fn into(self) -> U

    Calls U::from(self).

    +

    Fields§

    §pe: bool§id1: String§seq1: String§qual1: String§id2: String§seq2: String§qual2: String

    Trait Implementations§

    source§

    impl Clone for Seq

    source§

    fn clone(&self) -> Seq

    Returns a copy 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 Debug for Seq

    source§

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

    Formats the value using the given formatter. Read more

    Auto Trait Implementations§

    §

    impl RefUnwindSafe for Seq

    §

    impl Send for Seq

    §

    impl Sync for Seq

    §

    impl Unpin for Seq

    §

    impl UnwindSafe for Seq

    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> 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 Twhere - T: Clone,

    §

    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 Twhere - U: Into<T>,

    §

    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 Twhere - U: TryFrom<T>,

    §

    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.
    \ No newline at end of file +From<T> for U chooses to do.

    +
    source§

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

    §

    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>,

    §

    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>,

    §

    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.
    \ No newline at end of file diff --git a/docs/fasten_straighten/all.html b/docs/fasten_straighten/all.html index 48216773..0bc67563 100644 --- a/docs/fasten_straighten/all.html +++ b/docs/fasten_straighten/all.html @@ -1 +1,2 @@ -List of all items in this crate

    List of all items

    Functions

    \ No newline at end of file +List of all items in this crate +

    List of all items

    Functions

    \ No newline at end of file diff --git a/docs/fasten_straighten/fn.main.html b/docs/fasten_straighten/fn.main.html index c0c3bc27..0f492157 100644 --- a/docs/fasten_straighten/fn.main.html +++ b/docs/fasten_straighten/fn.main.html @@ -1 +1,2 @@ -main in fasten_straighten - Rust

    Function fasten_straighten::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_straighten - Rust +

    Function fasten_straighten::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_straighten/index.html b/docs/fasten_straighten/index.html index 9465989d..81eecdff 100644 --- a/docs/fasten_straighten/index.html +++ b/docs/fasten_straighten/index.html @@ -1,10 +1,12 @@ -fasten_straighten - Rust
    Expand description

    Convert a fastq file to a standard 4-lines-per-entry format

    -

    Examples

    cat weird.fastq | fasten_straighten > four-per-entry.fastq
    -

    Usage

    Usage: fasten_straighten [-h] [-n INT] [-p] [-v]
    +fasten_straighten - Rust
    +    
    Expand description

    Convert a fastq file to a standard 4-lines-per-entry format

    +

    §Examples

    cat weird.fastq | fasten_straighten > four-per-entry.fastq
    +

    §Usage

    Usage: fasten_straighten [-h] [-n INT] [-p] [-v]
      
     Options:
         -h, --help          Print this help menu.
         -n, --numcpus INT   Number of CPUs (default: 1)
         -p, --paired-end    The input reads are interleaved paired-end
         -v, --verbose       Print more status messages
    -

    Functions

    \ No newline at end of file +

    Functions§

    \ No newline at end of file diff --git a/docs/fasten_trim/all.html b/docs/fasten_trim/all.html index f1df3ba4..a6a45b6b 100644 --- a/docs/fasten_trim/all.html +++ b/docs/fasten_trim/all.html @@ -1 +1,2 @@ -List of all items in this crate

    List of all items

    Functions

    \ No newline at end of file +List of all items in this crate +

    List of all items

    Functions

    \ No newline at end of file diff --git a/docs/fasten_trim/fn.main.html b/docs/fasten_trim/fn.main.html index 38888c5f..8afb44e6 100644 --- a/docs/fasten_trim/fn.main.html +++ b/docs/fasten_trim/fn.main.html @@ -1 +1,2 @@ -main in fasten_trim - Rust

    Function fasten_trim::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_trim - Rust +

    Function fasten_trim::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_trim/fn.read_fasta.html b/docs/fasten_trim/fn.read_fasta.html new file mode 100644 index 00000000..607ffdf2 --- /dev/null +++ b/docs/fasten_trim/fn.read_fasta.html @@ -0,0 +1,3 @@ +read_fasta in fasten_trim - Rust +

    Function fasten_trim::read_fasta

    source ·
    pub(crate) fn read_fasta(file_path: &str) -> HashMap<String, String>
    Expand description

    Read a fasta file and return a HashMap of the sequences

    +
    \ No newline at end of file diff --git a/docs/fasten_trim/fn.trim_worker.html b/docs/fasten_trim/fn.trim_worker.html index 19c87a8e..44e3489b 100644 --- a/docs/fasten_trim/fn.trim_worker.html +++ b/docs/fasten_trim/fn.trim_worker.html @@ -1,6 +1,8 @@ -trim_worker in fasten_trim - Rust

    Function fasten_trim::trim_worker

    source ·
    pub(crate) fn trim_worker(
    +trim_worker in fasten_trim - Rust
    +    

    Function fasten_trim::trim_worker

    source ·
    pub(crate) fn trim_worker(
         seq: Seq,
    -    first_base: usize,
    -    last_base: usize
    -) -> String
    Expand description

    Trim a set of fastq entries and send it to a channel

    + suggested_first_base: usize, + suggested_last_base: usize, + adapters: &Vec<String> +) -> String
    Expand description

    Trim a set of fastq entries and send it to a channel

    \ No newline at end of file diff --git a/docs/fasten_trim/index.html b/docs/fasten_trim/index.html index 60babeda..985ecc18 100644 --- a/docs/fasten_trim/index.html +++ b/docs/fasten_trim/index.html @@ -1,8 +1,16 @@ -fasten_trim - Rust

    Crate fasten_trim

    source ·
    Expand description

    Blunt-end trims using 0-based coordinates

    -

    Examples

    Trim five bases from the right side

    cat file.fastq | fasten_trim -l -5 > trimmed.fastq
    -

    Keep a maximum of 100bp

    cat file.fastq | fasten_trim -l 99 > trimmed.fastq
    -

    Trim 5bp from the left side

    cat file.fastq | fasten_trim -f 4  > trimmed.fastq
    -

    Usage

    Usage: fasten_trim [-h] [-n INT] [-p] [-v] [-f INT] [-l INT]
    +fasten_trim - Rust
    +    

    Crate fasten_trim

    source ·
    Expand description

    Trims reads using 0-based coordinates

    +

    §Examples

    §Adapters

    §Download the adapter files

    mkdir -pv $HOME/db
    +pushd $HOME/db # step into the db directory
    +git clone https://github.com/lskatz/adapterseqs
    +ADAPTERS=$(find $HOME/db/adapterseqs -name '*.fa')
    +popd # return to the original directory
    +

    §Trim the adapters

    cat file.fastq | fasten_trim 
    +

    §Blunt-end trim five bases from the right side

    cat file.fastq | fasten_trim -l -5 > trimmed.fastq
    +

    §Keep a maximum of 100bp with blunt-end trimming on the right side

    cat file.fastq | fasten_trim -l 99 > trimmed.fastq
    +

    §Blunt-end trim 5bp from the left side

    cat file.fastq | fasten_trim -f 4  > trimmed.fastq
    +

    §Usage

    Usage: fasten_trim [-h] [-n INT] [-p] [-v] [-f INT] [-l INT]
      
     Options:
         -h, --help          Print this help menu.
    @@ -11,6 +19,18 @@ 

    Examples

    Functions

    • main 🔒
    • Trim a set of fastq entries and send it to a channel
    \ No newline at end of file + -l, --last-base INT The last base to keep. (default: 0) +

    §Notes

    +

    The algorithm is as follows:

    +
      +
    1. marks the first and last bases for trimming as 0 and the last base, respectively
    2. +
    3. if an adapter is found at the beginning of the sequence, then move the marker for where it will be trimmed
    4. +
    5. Compare the blunt end suggested trimming against where an adapter might be found and move the marker as the most inward possible
    6. +
    7. Trim the sequence and quality strings
    8. +
    +

    §Output

    +

    The deflines will be altered with a description of the trimming using key=value syntax, separated by spaces, e.g., +@M03235:53:000000000-AHLTD:1:1101:1826:14428 trimmed_adapter_rev=TT trimmed_left=0 trimmed_right=249 +or for a forward adapter, +@M03235:53:000000000-AHLTD:1:1101:1758:14922 trimmed_adapter_fwd=AA trimmed_left=2 trimmed_right=251

    +

    Functions§

    • main 🔒
    • read_fasta 🔒
      Read a fasta file and return a HashMap of the sequences
    • Trim a set of fastq entries and send it to a channel
    \ No newline at end of file diff --git a/docs/fasten_trim/sidebar-items.js b/docs/fasten_trim/sidebar-items.js index 4a9ce055..d86ceb7a 100644 --- a/docs/fasten_trim/sidebar-items.js +++ b/docs/fasten_trim/sidebar-items.js @@ -1 +1 @@ -window.SIDEBAR_ITEMS = {"fn":["main","trim_worker"]}; \ No newline at end of file +window.SIDEBAR_ITEMS = {"fn":["main","read_fasta","trim_worker"]}; \ No newline at end of file diff --git a/docs/fasten_validate/all.html b/docs/fasten_validate/all.html index b366368c..d6cf1b86 100644 --- a/docs/fasten_validate/all.html +++ b/docs/fasten_validate/all.html @@ -1 +1,2 @@ -List of all items in this crate

    List of all items

    Functions

    \ No newline at end of file +List of all items in this crate +

    List of all items

    Functions

    \ No newline at end of file diff --git a/docs/fasten_validate/fn.main.html b/docs/fasten_validate/fn.main.html index e731cd5c..ab565f8d 100644 --- a/docs/fasten_validate/fn.main.html +++ b/docs/fasten_validate/fn.main.html @@ -1 +1,2 @@ -main in fasten_validate - Rust

    Function fasten_validate::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file +main in fasten_validate - Rust +

    Function fasten_validate::main

    source ·
    pub(crate) fn main()
    \ No newline at end of file diff --git a/docs/fasten_validate/index.html b/docs/fasten_validate/index.html index 1c74df8a..6eaf2d9f 100644 --- a/docs/fasten_validate/index.html +++ b/docs/fasten_validate/index.html @@ -1,7 +1,9 @@ -fasten_validate - Rust

    Crate fasten_validate

    source ·
    Expand description

    Validates your reads and makes you feel good about yourself!

    -

    Examples

    Quick validation with stderr message

    cat file.fastq | fasten_validate --verbose
    -

    Validate that your reads are paired end

    cat R1.fastq R2.fastq | fasten_shuffle | fasten_validate --paired-end
    -

    Parallelize

    +fasten_validate - Rust +

    Crate fasten_validate

    source ·
    Expand description

    Validates your reads and makes you feel good about yourself!

    +

    §Examples

    §Quick validation with stderr message

    cat file.fastq | fasten_validate --verbose
    +

    §Validate that your reads are paired end

    cat R1.fastq R2.fastq | fasten_shuffle | fasten_validate --paired-end
    +

    §Parallelize

    Large-scale validation of PE reads with 4 CPUs and xargs

    \ls *_1.fastq.gz | xargs -n 1 -P 4 bash -c '
    @@ -10,7 +12,7 @@ 

    Examples

    Usage

        Usage: fasten_validate [-h] [-n INT] [-p] [-v] [--min-length INT] [--min-quality FLOAT] [--paired-end] [--print-reads] [-v]
    +

    §Usage

        Usage: fasten_validate [-h] [-n INT] [-p] [-v] [--min-length INT] [--min-quality FLOAT] [--paired-end] [--print-reads] [-v]
          
         Options:
             -h, --help          Print this help menu.
    @@ -24,4 +26,4 @@ 

    Examples

    Functions

    \ No newline at end of file +

    Functions§

    \ No newline at end of file diff --git a/docs/help.html b/docs/help.html index b0bdad59..43e9fbe6 100644 --- a/docs/help.html +++ b/docs/help.html @@ -1 +1,2 @@ -Rustdoc help

    Rustdoc help

    Back
    \ No newline at end of file +Help +

    Rustdoc help

    Back
    \ No newline at end of file diff --git a/docs/search-index.js b/docs/search-index.js index a879e00f..b4216f38 100644 --- a/docs/search-index.js +++ b/docs/search-index.js @@ -1,26 +1,26 @@ -var searchIndex = JSON.parse('{\ -"fasten":{"doc":"Perform random operations on fastq files, using unix …","t":"FFFAFOAADLLLLLLLLLLLIDKLLLLLLLKLMLKLKLKLKLMKLMKLMMLKLKLLLL","n":["eexit","fasten_base_options","fasten_base_options_matches","io","logmsg","print","fastq","seq","FastqReader","borrow","borrow_mut","from","into","into_iter","new","new_careful","next","try_from","try_into","type_id","Cleanable","Seq","blank","blank","borrow","borrow_mut","clone","clone_into","fmt","from","from_string","from_string","id","into","is_blank","is_blank","is_high_quality","is_high_quality","lower_ambiguity_q","lower_ambiguity_q","new","new","pairid","print","print","qual","sanitize_id","sanitize_id","seq","thresholds","to_owned","to_string","to_string","trim","trim","try_from","try_into","type_id"],"q":[[0,"fasten"],[6,"fasten::io"],[8,"fasten::io::fastq"],[20,"fasten::io::seq"]],"d":["Propagate an error by printing invalid read(s)","a function that reads an options object and adds fasten …","a function that processes the options on the command line …","input/output methods","Print a formatted message to stderr ","Rewrite print!() so that it doesn’t panic on broken pipe.","","","A FastQ reader","","","Returns the argument unchanged.","Calls U::from(self).","","","","There are two flavors of next: either read quickly or …","","","","A sequence that can be cleaned","A sequence struct that contains the ID, sequence, and …","Make a blank sequence object.","Make a blank sequence object.","","","","","","Returns the argument unchanged.","Make a seq object from a String.","Create a sequence object from a string. TODO make it more …","","Calls U::from(self).","Determine if it is a blank sequence.","Determine if it is a blank sequence.","Reports bool whether the read passes thresholds.","Reports bool whether the read passes thresholds.","lower any low quality base to a zero and “N”","Alter any ambiguity site with a quality=0","new sequence object","Make a new cleanable sequence object","","Print the result of to_string()","","","sanitize an identifier string","Read an identifier and return a cleaned version, e.g., …","","","","Make a String object","","Trim sequences based on quality","Trim the ends of reads with low quality","","",""],"i":[0,0,0,0,0,0,0,0,0,6,6,6,6,6,6,6,6,6,6,6,0,0,15,7,7,7,7,7,7,7,15,7,7,7,15,7,15,7,15,7,15,7,7,15,7,7,15,7,7,7,7,15,7,15,7,7,7,7],"f":[[[]],[[],1],[[2,1],3],0,[[[4,[2]]]],0,0,0,0,[[]],[[]],[[]],[[]],[[]],[5,[[6,[5]]]],[5,[[6,[5]]]],[[[6,[5]]],[[8,[7]]]],[[],9],[[],9],[[],10],0,0,[[],7],[[],7],[[]],[[]],[7,7],[[]],[[7,11],12],[[]],[13,7],[13,7],0,[[]],[[],14],[7,14],[[],14],[7,14],[[]],[7],[[13,13,13],7],[[13,13,13],7],0,[[]],[7],0,[13,13],[13,13],0,0,[[]],[[],13],[7,13],[[]],[7],[[],9],[[],9],[[],10]],"c":[],"p":[[3,"Options"],[15,"str"],[3,"Matches"],[8,"AsRef"],[8,"Read"],[3,"FastqReader"],[3,"Seq"],[4,"Option"],[4,"Result"],[3,"TypeId"],[3,"Formatter"],[6,"Result"],[3,"String"],[15,"bool"],[8,"Cleanable"]]},\ -"fasten_clean":{"doc":"Trim and filter reads","t":"FFF","n":["avg_quality","main","trim"],"q":[[0,"fasten_clean"]],"d":["Determine average quality of a qual cigar string, e.g., …","","Trim the ends of reads with low quality"],"i":[0,0,0],"f":[[1,2],[[]],[[1,1,3]]],"c":[],"p":[[3,"String"],[15,"f32"],[15,"u8"]]},\ -"fasten_combine":{"doc":"Collapse identical reads into single reads, recalculating …","t":"RRFF","n":["READ_SEPARATOR","TEN","combine_error_vectors","main"],"q":[[0,"fasten_combine"]],"d":["Glues together paired end reads internally and is a …","need this constant because the compiler had a problem with …","Combines vectors of error probabilities such that the rate …",""],"i":[0,0,0,0],"f":[0,0,[[[2,[1]],[2,[1]]],[[2,[1]]]],[[]]],"c":[],"p":[[15,"f32"],[3,"Vec"]]},\ -"fasten_convert":{"doc":"Convert between different sequence formats","t":"DLLLLLLLLLMMLFLMMFFFMMLLLLFFF","n":["FastenSeq","as_fasta","as_fastq","as_sam","borrow","borrow_mut","clone","clone_into","fmt","from","id1","id2","into","main","new","qual1","qual2","read_fasta","read_fastq","read_sam","seq1","seq2","to_owned","try_from","try_into","type_id","write_fasta","write_fastq","write_sam"],"q":[[0,"fasten_convert"]],"d":["Struct that can handle paired end reads","Return a formatted string as a fasta entry","Return a formatted string as a fastq entry","Return a formatted string as a sam entry","","","","","","Returns the argument unchanged.","","","Calls U::from(self).","","a blank new object is a set of blank strings for each value","","","Read fasta from stdin and transmit it to a channel","Read fastq from stdin and transmit it to a channel","Read sam from stdin and transmit it to a channel","","","","","","","Read from a channel and print as fasta","Read from a channel and print as fastq","Read from a channel and print as sam"],"i":[0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0],"f":[0,[1,2],[1,2],[1,2],[[]],[[]],[1,1],[[]],[[1,3],4],[[]],0,0,[[]],[[]],[[],1],0,0,[[[5,[1]],6]],[[[5,[1]],6]],[[[5,[1]],6]],0,0,[[]],[[],7],[[],7],[[],8],[[[9,[1]]]],[[[9,[1]]]],[[[9,[1]]]]],"c":[],"p":[[3,"FastenSeq"],[3,"String"],[3,"Formatter"],[6,"Result"],[3,"Sender"],[15,"bool"],[4,"Result"],[3,"TypeId"],[3,"Receiver"]]},\ -"fasten_inspect":{"doc":"Marks up your reads with useful information like read …","t":"FF","n":["main","validate_reads"],"q":[[0,"fasten_inspect"]],"d":["","marks up reads from stdin"],"i":[0,0],"f":[[[]],[[1,2,2]]],"c":[],"p":[[15,"u8"],[3,"Regex"]]},\ -"fasten_kmer":{"doc":"Counts kmers. Each line is a kmer with two columns …","t":"RFFFFF","n":["READ_SEPARATOR","count_kmers","kmers_in_str","main","revcomp","switch_base"],"q":[[0,"fasten_kmer"]],"d":["Glues together paired end reads internally and is a …","Read fastq from stdin and count kmers","Read a str of nucleotides and count kmers. If …","","reverse-complement a dna sequence","Complementary nucleotide for ACTGUN, case insensitive"],"i":[0,0,0,0,0,0],"f":[0,[[1,2,3,3,3]],[[4,2,3],[[7,[5,6]]]],[[]],[4,5],[8,8]],"c":[],"p":[[3,"Stdin"],[15,"usize"],[15,"bool"],[15,"str"],[3,"String"],[15,"u32"],[3,"HashMap"],[15,"char"]]},\ -"fasten_metrics":{"doc":"Gives read metrics on a read set. Values are given in a …","t":"FFF","n":["average_quality","main","standard_deviation"],"q":[[0,"fasten_metrics"]],"d":["given a cigar line for quality, return its average","","Local implementation of standard deviation"],"i":[0,0,0],"f":[[1,2],[[]],[[[3,[2]]],2]],"c":[],"p":[[15,"str"],[15,"f32"],[3,"Vec"]]},\ -"fasten_mutate":{"doc":"Mutates reads. There is no mutation model; only randomness.","t":"FF","n":["main","mutate"],"q":[[0,"fasten_mutate"]],"d":["","Mutate a str of a sequence of nucleotides using the …"],"i":[0,0],"f":[[[]],[[1,[3,[2]],4,5],6]],"c":[],"p":[[15,"str"],[15,"char"],[3,"Vec"],[15,"u8"],[15,"bool"],[3,"String"]]},\ -"fasten_normalize":{"doc":"Normalizes kmer depth by removing some reads from high …","t":"RFFF","n":["READ_SEPARATOR","main","normalize_coverage","print_reads"],"q":[[0,"fasten_normalize"]],"d":["Glues together paired end reads internally and is a …","","Normalize the coverage to a certain target and print as a …","Print the reads in fastq format when given in a single …"],"i":[0,0,0,0],"f":[0,[[]],[[1,2,3]],[[[5,[4]]]]],"c":[],"p":[[3,"Stdin"],[15,"u32"],[15,"bool"],[15,"str"],[3,"Vec"]]},\ -"fasten_pe":{"doc":"Determine paired-end-ness in an interleaved file. Exit …","t":"FFF","n":["is_paired_end_miseq","is_paired_end_slash12","main"],"q":[[0,"fasten_pe"]],"d":["Detect whether the vector of IDs represent paired-endedness","Detect whether the vector of IDs represent paired-endedness",""],"i":[0,0,0],"f":[[[[2,[1]],[2,[1]]],3],[[[2,[1]],[2,[1]]],3],[[]]],"c":[],"p":[[3,"String"],[3,"Vec"],[15,"u8"]]},\ -"fasten_progress":{"doc":"Prints a progress meter for number of fastq entries to …","t":"F","n":["main"],"q":[[0,"fasten_progress"]],"d":[""],"i":[0],"f":[[[]]],"c":[],"p":[]},\ -"fasten_quality_filter":{"doc":"Transforms any low-quality base to ‘N’","t":"F","n":["main"],"q":[[0,"fasten_quality_filter"]],"d":[""],"i":[0],"f":[[[]]],"c":[],"p":[]},\ -"fasten_randomize":{"doc":"Create random reads from stdin.","t":"FF","n":["main","print_reads_from_stdin"],"q":[[0,"fasten_randomize"]],"d":["","Read fastq from stdin, add the reads to a vector, then …"],"i":[0,0],"f":[[[]],[1]],"c":[],"p":[[15,"u32"]]},\ -"fasten_regex":{"doc":"Filter reads based on a regular expression.","t":"F","n":["main"],"q":[[0,"fasten_regex"]],"d":[""],"i":[0],"f":[[[]]],"c":[],"p":[]},\ -"fasten_repair":{"doc":"Repairs reads from fasten_inspect output","t":"FFF","n":["main","repair_one_read","repair_reads"],"q":[[0,"fasten_repair"]],"d":["","Repair exactly one read","Repairs reads depending on the deflines by calling …"],"i":[0,0,0],"f":[[[]],[[1,1,1,1,2,3,4,2]],[[2,3,4,2,5]]],"c":[],"p":[[3,"String"],[15,"bool"],[15,"usize"],[15,"f32"],[15,"str"]]},\ -"fasten_replace":{"doc":"Streaming editor for fastq data using a find/replace.","t":"F","n":["main"],"q":[[0,"fasten_replace"]],"d":[""],"i":[0],"f":[[[]]],"c":[],"p":[]},\ -"fasten_sample":{"doc":"downsample your reads","t":"FF","n":["main","rand_32"],"q":[[0,"fasten_sample"]],"d":["","Generate a set of random floats"],"i":[0,0],"f":[[[]],[[],[[2,[1]]]]],"c":[],"p":[[15,"f32"],[3,"Vec"]]},\ -"fasten_shuffle":{"doc":"Interleaves reads from either stdin or file parameters.","t":"FFFF","n":["deshuffle","main","read_seqs","shuffle"],"q":[[0,"fasten_shuffle"]],"d":["Read from stdin and deshuffle reads into files","","Read fastq entries from a filename","Read fastq from stdin and interleave"],"i":[0,0,0,0],"f":[[1],[[]],[2,[[4,[3]]]],[1]],"c":[],"p":[[3,"Matches"],[3,"String"],[3,"Seq"],[3,"Vec"]]},\ -"fasten_sort":{"doc":"Sort a fastq file. If the reads are paired end, then the …","t":"DLLLLLLMMLFMMMMMFLLLL","n":["Seq","borrow","borrow_mut","clone","clone_into","fmt","from","id1","id2","into","main","pe","qual1","qual2","seq1","seq2","sort_entries","to_owned","try_from","try_into","type_id"],"q":[[0,"fasten_sort"]],"d":["A sequence struct that is paired-end aware","","","","","","Returns the argument unchanged.","","","Calls U::from(self).","","","","","","","Sort fastq entries in a vector","","","",""],"i":[0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1],"f":[0,[[]],[[]],[1,1],[[]],[[1,2],3],[[]],0,0,[[]],[[]],0,0,0,0,0,[[[4,[1]],5,6],[[4,[1]]]],[[]],[[],7],[[],7],[[],8]],"c":[],"p":[[3,"Seq"],[3,"Formatter"],[6,"Result"],[3,"Vec"],[15,"str"],[15,"bool"],[4,"Result"],[3,"TypeId"]]},\ -"fasten_straighten":{"doc":"Convert a fastq file to a standard 4-lines-per-entry format","t":"F","n":["main"],"q":[[0,"fasten_straighten"]],"d":[""],"i":[0],"f":[[[]]],"c":[],"p":[]},\ -"fasten_trim":{"doc":"Blunt-end trims using 0-based coordinates","t":"FF","n":["main","trim_worker"],"q":[[0,"fasten_trim"]],"d":["","Trim a set of fastq entries and send it to a channel"],"i":[0,0],"f":[[[]],[[1,2,2],3]],"c":[],"p":[[3,"Seq"],[15,"usize"],[3,"String"]]},\ -"fasten_validate":{"doc":"Validates your reads and makes you feel good about …","t":"F","n":["main"],"q":[[0,"fasten_validate"]],"d":[""],"i":[0],"f":[[[]]],"c":[],"p":[]}\ -}'); -if (typeof window !== 'undefined' && window.initSearch) {window.initSearch(searchIndex)}; -if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex}; +var searchIndex = new Map(JSON.parse('[\ +["fasten",{"doc":"Perform random operations on fastq files, using unix …","t":"HHHCHQHCCFNNNNNNNNNNNKFMNNNNNNNMNONMNMNMNMNOMNOMNOONMNMNNNN","n":["eexit","fasten_base_options","fasten_base_options_matches","io","logmsg","print","reverse_complement","fastq","seq","FastqReader","borrow","borrow_mut","from","into","into_iter","new","new_careful","next","try_from","try_into","type_id","Cleanable","Seq","blank","blank","borrow","borrow_mut","clone","clone_into","fmt","from","from_string","from_string","id","into","is_blank","is_blank","is_high_quality","is_high_quality","lower_ambiguity_q","lower_ambiguity_q","new","new","pairid","print","print","qual","sanitize_id","sanitize_id","seq","thresholds","to_owned","to_string","to_string","trim","trim","try_from","try_into","type_id"],"q":[[0,"fasten"],[7,"fasten::io"],[9,"fasten::io::fastq"],[21,"fasten::io::seq"],[59,"getopts"],[60,"getopts"],[61,"alloc::string"],[62,"std::io"],[63,"core::option"],[64,"core::result"],[65,"core::any"],[66,"core::fmt"],[67,"core::fmt"]],"d":["Propagate an error by printing invalid read(s)","a function that reads an options object and adds fasten …","a function that processes the options on the command line …","input/output methods","Print a formatted message to stderr ","Rewrite print!() so that it doesn’t panic on broken pipe.","Reverse complement a DNA sequence. Take into account …","","","A FastQ reader","","","Returns the argument unchanged.","Calls U::from(self).","","","","There are two flavors of next: either read quickly or …","","","","A sequence that can be cleaned","A sequence struct that contains the ID, sequence, and …","Make a blank sequence object.","Make a blank sequence object.","","","","","","Returns the argument unchanged.","Make a seq object from a String.","Create a sequence object from a string. TODO make it more …","","Calls U::from(self).","Determine if it is a blank sequence.","Determine if it is a blank sequence.","Reports bool whether the read passes thresholds.","Reports bool whether the read passes thresholds.","lower any low quality base to a zero and “N”","Alter any ambiguity site with a quality=0","new sequence object","Make a new cleanable sequence object","","Print the result of to_string()","","","sanitize an identifier string","Read an identifier and return a cleaned version, e.g., …","","","","Make a String object","","Trim sequences based on quality","Trim the ends of reads with low quality","","",""],"i":[0,0,0,0,0,0,0,0,0,0,7,7,7,7,7,7,7,7,7,7,7,0,0,15,9,9,9,9,9,9,9,15,9,9,9,15,9,15,9,15,9,15,9,9,15,9,9,15,9,9,9,9,15,9,15,9,9,9,9],"f":"{{}b}{{}d}{{fd}h}`{cb{{j{f}}}}`{fl}```{ce{}{}}0{cc{}}11{c{{n{c}}}A`}0{{{n{c}}}{{Ad{Ab}}}A`}{c{{Af{e}}}{}{}}0{cAh{}}``{{}Ab}066{AbAb}{{ce}b{}{}}{{AbAj}Al}8{lAb}0`:{AnB`}{AbB`}10{Anb}{Abb}{{lll}Ab}0`21`{ll}0``{ce{}{}}{Anl}{Abl}65??>","c":[],"p":[[1,"unit"],[5,"Options",59],[1,"str"],[5,"Matches",59],[10,"AsRef",60],[5,"String",61],[5,"FastqReader",9],[10,"Read",62],[5,"Seq",21],[6,"Option",63],[6,"Result",64],[5,"TypeId",65],[5,"Formatter",66],[8,"Result",66],[10,"Cleanable",21],[1,"bool"]],"b":[]}],\ +["fasten_clean",{"doc":"Trim and filter reads","t":"HHH","n":["avg_quality","main","trim"],"q":[[0,"fasten_clean"],[3,"alloc::string"]],"d":["Determine average quality of a qual cigar string, e.g., …","","Trim the ends of reads with low quality"],"i":[0,0,0],"f":"{bd}{{}f}{{bbh}{{j{bb}}}}","c":[],"p":[[5,"String",3],[1,"f32"],[1,"unit"],[1,"u8"],[1,"tuple"]],"b":[]}],\ +["fasten_combine",{"doc":"Collapse identical reads into single reads, recalculating …","t":"SSHH","n":["READ_SEPARATOR","TEN","combine_error_vectors","main"],"q":[[0,"fasten_combine"],[4,"alloc::vec"]],"d":["Glues together paired end reads internally and is a …","need this constant because the compiler had a problem with …","Combines vectors of error probabilities such that the rate …",""],"i":[0,0,0,0],"f":"``{{{d{b}}{d{b}}}{{d{b}}}}{{}f}","c":[],"p":[[1,"f32"],[5,"Vec",4],[1,"unit"]],"b":[]}],\ +["fasten_convert",{"doc":"Convert between different sequence formats","t":"FNNNNNNNNNOONHNOOHHHOONNNNHHH","n":["FastenSeq","as_fasta","as_fastq","as_sam","borrow","borrow_mut","clone","clone_into","fmt","from","id1","id2","into","main","new","qual1","qual2","read_fasta","read_fastq","read_sam","seq1","seq2","to_owned","try_from","try_into","type_id","write_fasta","write_fastq","write_sam"],"q":[[0,"fasten_convert"],[29,"alloc::string"],[30,"core::fmt"],[31,"core::fmt"],[32,"core::result"],[33,"core::any"],[34,"std::sync::mpsc"]],"d":["Struct that can handle paired end reads","Return a formatted string as a fasta entry","Return a formatted string as a fastq entry","Return a formatted string as a sam entry","","","","","","Returns the argument unchanged.","","","Calls U::from(self).","","a blank new object is a set of blank strings for each value","","","Read fasta from stdin and transmit it to a channel","Read fastq from stdin and transmit it to a channel","Read sam from stdin and transmit it to a channel","","","","","","","Read from a channel and print as fasta","Read from a channel and print as fastq","Read from a channel and print as sam"],"i":[0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0],"f":"`{bd}00{ce{}{}}0{bb}{{ce}f{}{}}{{bh}j}{cc{}}``4{{}f}{{}b}``{{{l{b}}n}f}00``7{c{{A`{e}}}{}{}}0{cAb{}}{{{Ad{b}}}f}00","c":[],"p":[[5,"FastenSeq",0],[5,"String",29],[1,"unit"],[5,"Formatter",30],[8,"Result",30],[5,"Sender",31],[1,"bool"],[6,"Result",32],[5,"TypeId",33],[5,"Receiver",31]],"b":[]}],\ +["fasten_inspect",{"doc":"Marks up your reads with useful information like read …","t":"HH","n":["main","validate_reads"],"q":[[0,"fasten_inspect"],[2,"regex::regex::string"]],"d":["","marks up reads from stdin"],"i":[0,0],"f":"{{}b}{{dff}b}","c":[],"p":[[1,"unit"],[1,"u8"],[5,"Regex",2]],"b":[]}],\ +["fasten_kmer",{"doc":"Counts kmers. Each line is a kmer with two columns …","t":"SHHHHH","n":["READ_SEPARATOR","count_kmers","kmers_in_str","main","revcomp","switch_base"],"q":[[0,"fasten_kmer"],[6,"std::io::stdio"],[7,"alloc::string"],[8,"std::collections::hash::map"]],"d":["Glues together paired end reads internally and is a …","Read fastq from stdin and count kmers","Read a str of nucleotides and count kmers. If …","","reverse-complement a dna sequence","Complementary nucleotide for ACTGUN, case insensitive"],"i":[0,0,0,0,0,0],"f":"`{{bdfff}h}{{jdf}{{A`{ln}}}}{{}h}{jl}{AbAb}","c":[],"p":[[5,"Stdin",6],[1,"usize"],[1,"bool"],[1,"unit"],[1,"str"],[5,"String",7],[1,"u32"],[5,"HashMap",8],[1,"char"]],"b":[]}],\ +["fasten_metrics",{"doc":"Gives read metrics on a read set. Values are given in a …","t":"HHH","n":["average_quality","main","standard_deviation"],"q":[[0,"fasten_metrics"],[3,"alloc::vec"]],"d":["given a cigar line for quality, return its average","","Local implementation of standard deviation"],"i":[0,0,0],"f":"{bd}{{}f}{{{h{d}}}d}","c":[],"p":[[1,"str"],[1,"f32"],[1,"unit"],[5,"Vec",3]],"b":[]}],\ +["fasten_mutate",{"doc":"Mutates reads. There is no mutation model; only randomness.","t":"HH","n":["main","mutate"],"q":[[0,"fasten_mutate"],[2,"alloc::vec"],[3,"alloc::string"]],"d":["","Mutate a str of a sequence of nucleotides using the …"],"i":[0,0],"f":"{{}b}{{d{h{f}}jl}n}","c":[],"p":[[1,"unit"],[1,"str"],[1,"char"],[5,"Vec",2],[1,"u8"],[1,"bool"],[5,"String",3]],"b":[]}],\ +["fasten_normalize",{"doc":"Normalizes kmer depth by removing some reads from high …","t":"SHHH","n":["READ_SEPARATOR","main","normalize_coverage","print_reads"],"q":[[0,"fasten_normalize"],[4,"std::io::stdio"],[5,"alloc::vec"]],"d":["Glues together paired end reads internally and is a …","","Normalize the coverage to a certain target and print as a …","Print the reads in fastq format when given in a single …"],"i":[0,0,0,0],"f":"`{{}b}{{dfh}b}{{{l{j}}}b}","c":[],"p":[[1,"unit"],[5,"Stdin",4],[1,"u32"],[1,"bool"],[1,"str"],[5,"Vec",5]],"b":[]}],\ +["fasten_pe",{"doc":"Determine paired-end-ness in an interleaved file. Exit …","t":"HHH","n":["is_paired_end_miseq","is_paired_end_slash12","main"],"q":[[0,"fasten_pe"],[3,"alloc::string"],[4,"alloc::vec"]],"d":["Detect whether the vector of IDs represent paired-endedness","Detect whether the vector of IDs represent paired-endedness",""],"i":[0,0,0],"f":"{{{d{b}}{d{b}}}f}0{{}h}","c":[],"p":[[5,"String",3],[5,"Vec",4],[1,"u8"],[1,"unit"]],"b":[]}],\ +["fasten_progress",{"doc":"Prints a progress meter for number of fastq entries to …","t":"H","n":["main"],"q":[[0,"fasten_progress"]],"d":[""],"i":[0],"f":"{{}b}","c":[],"p":[[1,"unit"]],"b":[]}],\ +["fasten_quality_filter",{"doc":"Transforms any low-quality base to ‘N’","t":"H","n":["main"],"q":[[0,"fasten_quality_filter"]],"d":[""],"i":[0],"f":"{{}b}","c":[],"p":[[1,"unit"]],"b":[]}],\ +["fasten_randomize",{"doc":"Create random reads from stdin.","t":"HH","n":["main","print_reads_from_stdin"],"q":[[0,"fasten_randomize"]],"d":["","Read fastq from stdin, add the reads to a vector, then …"],"i":[0,0],"f":"{{}b}{db}","c":[],"p":[[1,"unit"],[1,"u32"]],"b":[]}],\ +["fasten_regex",{"doc":"Filter reads based on a regular expression.","t":"H","n":["main"],"q":[[0,"fasten_regex"]],"d":[""],"i":[0],"f":"{{}b}","c":[],"p":[[1,"unit"]],"b":[]}],\ +["fasten_repair",{"doc":"Repairs reads from fasten_inspect output","t":"HHH","n":["main","repair_one_read","repair_reads"],"q":[[0,"fasten_repair"],[3,"alloc::string"]],"d":["","Repair exactly one read","Repairs reads depending on the deflines by calling …"],"i":[0,0,0],"f":"{{}b}{{ddddfhjf}{{l{dfd}}}}{{fhjfn}b}","c":[],"p":[[1,"unit"],[5,"String",3],[1,"bool"],[1,"usize"],[1,"f32"],[1,"tuple"],[1,"str"]],"b":[]}],\ +["fasten_replace",{"doc":"Streaming editor for fastq data using a find/replace.","t":"H","n":["main"],"q":[[0,"fasten_replace"]],"d":[""],"i":[0],"f":"{{}b}","c":[],"p":[[1,"unit"]],"b":[]}],\ +["fasten_sample",{"doc":"downsample your reads","t":"HH","n":["main","rand_32"],"q":[[0,"fasten_sample"],[2,"alloc::vec"]],"d":["","Generate a set of random floats"],"i":[0,0],"f":"{{}b}{{}{{f{d}}}}","c":[],"p":[[1,"unit"],[1,"f32"],[5,"Vec",2]],"b":[]}],\ +["fasten_shuffle",{"doc":"Interleaves reads from either stdin or file parameters.","t":"HHHH","n":["deshuffle","main","read_seqs","shuffle"],"q":[[0,"fasten_shuffle"],[4,"getopts"],[5,"alloc::string"],[6,"fasten::io::seq"],[7,"alloc::vec"]],"d":["Read from stdin and deshuffle reads into files","","Read fastq entries from a filename","Read fastq from stdin and interleave"],"i":[0,0,0,0],"f":"{bd}{{}d}{f{{j{h}}}}2","c":[],"p":[[5,"Matches",4],[1,"unit"],[5,"String",5],[5,"Seq",6],[5,"Vec",7]],"b":[]}],\ +["fasten_sort",{"doc":"Sort a fastq file. If the reads are paired end, then the …","t":"FNNNNNNOONHOOOOOHNNNN","n":["Seq","borrow","borrow_mut","clone","clone_into","fmt","from","id1","id2","into","main","pe","qual1","qual2","seq1","seq2","sort_entries","to_owned","try_from","try_into","type_id"],"q":[[0,"fasten_sort"],[21,"core::fmt"],[22,"core::fmt"],[23,"core::result"],[24,"core::any"]],"d":["A sequence struct that is paired-end aware","","","","","","Returns the argument unchanged.","","","Calls U::from(self).","","","","","","","Sort fastq entries in a vector","","","",""],"i":[0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1],"f":"`{ce{}{}}0{bb}{{ce}d{}{}}{{bf}h}{cc{}}``4{{}d}`````{{{j{b}}ln}{{j{b}}}}6{c{{A`{e}}}{}{}}0{cAb{}}","c":[],"p":[[5,"Seq",0],[1,"unit"],[5,"Formatter",21],[8,"Result",21],[5,"Vec",22],[1,"str"],[1,"bool"],[6,"Result",23],[5,"TypeId",24]],"b":[]}],\ +["fasten_straighten",{"doc":"Convert a fastq file to a standard 4-lines-per-entry format","t":"H","n":["main"],"q":[[0,"fasten_straighten"]],"d":[""],"i":[0],"f":"{{}b}","c":[],"p":[[1,"unit"]],"b":[]}],\ +["fasten_trim",{"doc":"Trims reads using 0-based coordinates","t":"HHH","n":["main","read_fasta","trim_worker"],"q":[[0,"fasten_trim"],[3,"alloc::string"],[4,"std::collections::hash::map"],[5,"fasten::io::seq"],[6,"alloc::vec"]],"d":["","Read a fasta file and return a HashMap of the sequences","Trim a set of fastq entries and send it to a channel"],"i":[0,0,0],"f":"{{}b}{d{{h{ff}}}}{{jll{n{f}}}f}","c":[],"p":[[1,"unit"],[1,"str"],[5,"String",3],[5,"HashMap",4],[5,"Seq",5],[1,"usize"],[5,"Vec",6]],"b":[]}],\ +["fasten_validate",{"doc":"Validates your reads and makes you feel good about …","t":"H","n":["main"],"q":[[0,"fasten_validate"]],"d":[""],"i":[0],"f":"{{}b}","c":[],"p":[[1,"unit"]],"b":[]}]\ +]')); +if (typeof exports !== 'undefined') exports.searchIndex = searchIndex; +else if (window.initSearch) window.initSearch(searchIndex); diff --git a/docs/settings.html b/docs/settings.html index a506b282..d3185c1e 100644 --- a/docs/settings.html +++ b/docs/settings.html @@ -1 +1,2 @@ -Rustdoc settings

    Rustdoc settings

    Back
    \ No newline at end of file +Settings +

    Rustdoc settings

    Back
    \ No newline at end of file diff --git a/docs/src-files.js b/docs/src-files.js index ee03011f..5bed1804 100644 --- a/docs/src-files.js +++ b/docs/src-files.js @@ -1,25 +1,25 @@ -var srcIndex = JSON.parse('{\ -"fasten":["",[["io",[],["fastq.rs","mod.rs","seq.rs"]]],["lib.rs"]],\ -"fasten_clean":["",[],["fasten_clean.rs"]],\ -"fasten_combine":["",[],["fasten_combine.rs"]],\ -"fasten_convert":["",[],["fasten_convert.rs"]],\ -"fasten_inspect":["",[],["fasten_inspect.rs"]],\ -"fasten_kmer":["",[],["fasten_kmer.rs"]],\ -"fasten_metrics":["",[],["fasten_metrics.rs"]],\ -"fasten_mutate":["",[],["fasten_mutate.rs"]],\ -"fasten_normalize":["",[],["fasten_normalize.rs"]],\ -"fasten_pe":["",[],["fasten_pe.rs"]],\ -"fasten_progress":["",[],["fasten_progress.rs"]],\ -"fasten_quality_filter":["",[],["fasten_quality_filter.rs"]],\ -"fasten_randomize":["",[],["fasten_randomize.rs"]],\ -"fasten_regex":["",[],["fasten_regex.rs"]],\ -"fasten_repair":["",[],["fasten_repair.rs"]],\ -"fasten_replace":["",[],["fasten_replace.rs"]],\ -"fasten_sample":["",[],["fasten_sample.rs"]],\ -"fasten_shuffle":["",[],["fasten_shuffle.rs"]],\ -"fasten_sort":["",[],["fasten_sort.rs"]],\ -"fasten_straighten":["",[],["fasten_straighten.rs"]],\ -"fasten_trim":["",[],["fasten_trim.rs"]],\ -"fasten_validate":["",[],["fasten_validate.rs"]]\ -}'); +var srcIndex = new Map(JSON.parse('[\ +["fasten",["",[["io",[],["fastq.rs","mod.rs","seq.rs"]]],["lib.rs"]]],\ +["fasten_clean",["",[],["fasten_clean.rs"]]],\ +["fasten_combine",["",[],["fasten_combine.rs"]]],\ +["fasten_convert",["",[],["fasten_convert.rs"]]],\ +["fasten_inspect",["",[],["fasten_inspect.rs"]]],\ +["fasten_kmer",["",[],["fasten_kmer.rs"]]],\ +["fasten_metrics",["",[],["fasten_metrics.rs"]]],\ +["fasten_mutate",["",[],["fasten_mutate.rs"]]],\ +["fasten_normalize",["",[],["fasten_normalize.rs"]]],\ +["fasten_pe",["",[],["fasten_pe.rs"]]],\ +["fasten_progress",["",[],["fasten_progress.rs"]]],\ +["fasten_quality_filter",["",[],["fasten_quality_filter.rs"]]],\ +["fasten_randomize",["",[],["fasten_randomize.rs"]]],\ +["fasten_regex",["",[],["fasten_regex.rs"]]],\ +["fasten_repair",["",[],["fasten_repair.rs"]]],\ +["fasten_replace",["",[],["fasten_replace.rs"]]],\ +["fasten_sample",["",[],["fasten_sample.rs"]]],\ +["fasten_shuffle",["",[],["fasten_shuffle.rs"]]],\ +["fasten_sort",["",[],["fasten_sort.rs"]]],\ +["fasten_straighten",["",[],["fasten_straighten.rs"]]],\ +["fasten_trim",["",[],["fasten_trim.rs"]]],\ +["fasten_validate",["",[],["fasten_validate.rs"]]]\ +]')); createSrcSidebar(); diff --git a/docs/src/fasten/io/fastq.rs.html b/docs/src/fasten/io/fastq.rs.html index ef6a3460..e40abcca 100644 --- a/docs/src/fasten/io/fastq.rs.html +++ b/docs/src/fasten/io/fastq.rs.html @@ -1,4 +1,6 @@ -fastq.rs - source
    1
    +fastq.rs - source
    +    
    1
     2
     3
     4
    @@ -183,22 +185,22 @@
     /// Test whether we can read the test data carefully.
     fn test_the_careful_reader () {
         use std::fs::File;
    -    let my_file = File::open("testdata/four_reads.fastq").expect("Could not open file");
    +    let my_file = File::open("testdata/four_reads.fastq").expect("Could not open file");
         let my_buffer=BufReader::new(my_file);
         let mut fastq_reader=FastqReader::new_careful(my_buffer);
    -    let seq_obj = fastq_reader.next().expect("Could not read four_reads.fastq");
    -    assert_eq!(seq_obj.seq.trim(), "AAAGTGCTCTTAACTTGTCCCGCTCCACATCAGCGCGACATCAATCGACATTAAACCGAGTATCTTGTCAGCCTGGGGTGACGATGCGTCCCATTAAAGT");
    +    let seq_obj = fastq_reader.next().expect("Could not read four_reads.fastq");
    +    assert_eq!(seq_obj.seq.trim(), "AAAGTGCTCTTAACTTGTCCCGCTCCACATCAGCGCGACATCAATCGACATTAAACCGAGTATCTTGTCAGCCTGGGGTGACGATGCGTCCCATTAAAGT");
     }
     
     #[test]
     /// Test whether we can read the test data quickly.
     fn test_the_fast_reader () {
         use std::fs::File;
    -    let my_file = File::open("testdata/four_reads.fastq").expect("Could not open file");
    +    let my_file = File::open("testdata/four_reads.fastq").expect("Could not open file");
         let my_buffer=BufReader::new(my_file);
         let mut fastq_reader=FastqReader::new(my_buffer);
    -    let seq_obj = fastq_reader.next().expect("Could not read four_reads.fastq");
    -    assert_eq!(seq_obj.seq.trim(), "AAAGTGCTCTTAACTTGTCCCGCTCCACATCAGCGCGACATCAATCGACATTAAACCGAGTATCTTGTCAGCCTGGGGTGACGATGCGTCCCATTAAAGT");
    +    let seq_obj = fastq_reader.next().expect("Could not read four_reads.fastq");
    +    assert_eq!(seq_obj.seq.trim(), "AAAGTGCTCTTAACTTGTCCCGCTCCACATCAGCGCGACATCAATCGACATTAAACCGAGTATCTTGTCAGCCTGGGGTGACGATGCGTCCCATTAAAGT");
     }
     
     /// A FastQ reader
    @@ -227,7 +229,7 @@
     
         /// There are two flavors of next: either read 
         /// quickly or read carefully, depending on the 
    -    /// 'quickly' bool.
    +    /// 'quickly' bool.
         fn next(&mut self) -> Option<Seq> {
             // Read a fastq entry but assume that there are only
             // four lines per entry (id, seq, plus, qual).
    @@ -239,7 +241,7 @@
                 // Read the ID of the entry
                 match self.reader.read_line(&mut id) {
                     Ok(n) => {
    -                    // if we're expecting an ID line, but
    +                    // if we're expecting an ID line, but
                         // there are zero bytes read, then we are
                         // at the end of the file. Break.
                         if n < 1 {
    @@ -247,17 +249,17 @@
                         }
                     }
                     Err(error) => {
    -                    panic!("ERROR: could not read the ID line: {}",error);
    +                    panic!("ERROR: could not read the ID line: {}",error);
                     }
                 };
     
    -            self.reader.read_line(&mut seq).expect("ERROR: could not read sequence line");
    +            self.reader.read_line(&mut seq).expect("ERROR: could not read sequence line");
             
                 // burn the plus sign
                 let mut _plus = String::new();
    -            self.reader.read_line(&mut _plus).expect("ERROR: plus sign line not found");
    +            self.reader.read_line(&mut _plus).expect("ERROR: plus sign line not found");
     
    -            self.reader.read_line(&mut qual).expect("ERROR: could not read qual line");
    +            self.reader.read_line(&mut qual).expect("ERROR: could not read qual line");
     
                 let seq = Seq::new(&id, &seq, &qual);
     
    @@ -266,7 +268,7 @@
             // Read a fastq entry in the most correct way possible,
             // allowing for whitespace in seq and qual lines.
             else {
    -            let whitespace_regex = Regex::new(r"(\s+)").expect("malformed regex");
    +            let whitespace_regex = Regex::new(r"(\s+)").expect("malformed regex");
     
                 let mut id=    String::new();
                 let mut seq=   String::new();
    @@ -275,7 +277,7 @@
                 // Read the ID of the entry
                 match self.reader.read_line(&mut id) {
                     Ok(n) => {
    -                    // if we're expecting an ID line, but
    +                    // if we're expecting an ID line, but
                         // there are zero bytes read, then we are
                         // at the end of the file. Break.
                         if n < 1 {
    @@ -283,56 +285,56 @@
                         }
                     }
                     Err(error) => {
    -                    panic!("ERROR: {}",error);
    +                    panic!("ERROR: {}",error);
                     }
                   
                 }
                 // Read the DNA line of the entry and count
                 // how long it is.
    -            'dna: loop{
    +            'dna: loop{
                     let mut buf = String::new();
                     match self.reader.read_line(&mut buf) {
                         Ok(n) => {
                             if n < 1 {
    -                            panic!("ERROR: incomplete entry (no seq line), seqid {}\nbuf {}", id.trim(),buf);
    +                            panic!("ERROR: incomplete entry (no seq line), seqid {}\nbuf {}", id.trim(),buf);
                             }
                             // if we hit the qual line, then it is a single
                             // character, +
    -                        else if &buf[0..1] == "+" {
    -                            break 'dna;
    +                        else if &buf[0..1] == "+" {
    +                            break 'dna;
                             }
                             else {
                                 seq.push_str(&buf);
                             }
                         }
                         Err(error) => {
    -                        panic!("ERROR while reading seq for ID {}: {}",id.trim(),error);
    +                        panic!("ERROR while reading seq for ID {}: {}",id.trim(),error);
                         }
                     }
                 }
                 // remove all whitespace
    -            seq = whitespace_regex.replace_all(&seq,"").into_owned();
    +            seq = whitespace_regex.replace_all(&seq,"").into_owned();
                 let read_length :usize=seq.len(); 
                 
                 // build onto the qual line until it has the right
                 // number of bytes.
    -            'qual: loop{
    +            'qual: loop{
                     let mut buf = String::new();
                     match self.reader.read_line(&mut buf) {
                         Ok(n) => {
                             if n < 1 {
    -                            panic!("ERROR: incomplete entry (no qual line), seqid {}\nbuf {}", id.trim(),buf);
    +                            panic!("ERROR: incomplete entry (no qual line), seqid {}\nbuf {}", id.trim(),buf);
                             }
                             else {
                               qual.push_str(&buf);
                             }
    -                        qual = whitespace_regex.replace_all(&qual,"").into_owned();
    +                        qual = whitespace_regex.replace_all(&qual,"").into_owned();
                             if qual.len() >= read_length {
    -                          break 'qual;
    +                          break 'qual;
                             }
                         }
                         Err(error) => {
    -                        panic!("ERROR while reading qual for ID {}: {}",buf.trim(),error);
    +                        panic!("ERROR while reading qual for ID {}: {}",buf.trim(),error);
                         }
                     }
                 }
    diff --git a/docs/src/fasten/io/mod.rs.html b/docs/src/fasten/io/mod.rs.html
    index ccee8f0f..aa8c4006 100644
    --- a/docs/src/fasten/io/mod.rs.html
    +++ b/docs/src/fasten/io/mod.rs.html
    @@ -1,4 +1,6 @@
    -mod.rs - source
    1
    +mod.rs - source
    +    
    1
     2
     3
     
    pub mod fastq;
    diff --git a/docs/src/fasten/io/seq.rs.html b/docs/src/fasten/io/seq.rs.html
    index 42332c55..6dc94588 100644
    --- a/docs/src/fasten/io/seq.rs.html
    +++ b/docs/src/fasten/io/seq.rs.html
    @@ -1,4 +1,6 @@
    -seq.rs - source
    1
    +seq.rs - source
    +    
    1
     2
     3
     4
    @@ -251,25 +253,25 @@
     #[test]
     /// Test whether a cleanable sequence is instantiated
     fn test_new_seq() {
    -    let id   = "MY_ID".to_string();
    -    let seq  = "AATNGGCC".to_string();
    -    let qual = "#ABCDE!!".to_string();
    +    let id   = "MY_ID".to_string();
    +    let seq  = "AATNGGCC".to_string();
    +    let qual = "#ABCDE!!".to_string();
         let cleanable = Seq::new(&id,&seq,&qual);
         
    -    let formatted = format!("@{}\n{}\n+\n{}", &id, &seq, &qual);
    +    let formatted = format!("@{}\n{}\n+\n{}", &id, &seq, &qual);
         assert_eq!(cleanable.to_string(), formatted);
     }
     #[test]
     /// Test whether a cleanable sequence can be cleaned
     fn test_cleanable() {
    -    let id   = "MY_ID".to_string();
    -    let seq  = "AATNGGCC".to_string();
    -    let qual = "#ABCDE!!".to_string();
    +    let id   = "MY_ID".to_string();
    +    let seq  = "AATNGGCC".to_string();
    +    let qual = "#ABCDE!!".to_string();
         let mut cleanable = Seq::new(&id,&seq,&qual);
         
         cleanable.lower_ambiguity_q();
         cleanable.trim();
    -    assert_eq!(cleanable.to_string(), "@MY_ID\nATNGG\n+\nAB!DE".to_string());
    +    assert_eq!(cleanable.to_string(), "@MY_ID\nATNGG\n+\nAB!DE".to_string());
     }
     
     
    @@ -295,7 +297,7 @@
         fn from_string (seq_str: &String) -> Seq;
         /// sanitize an identifier string
         fn sanitize_id(id: &String) -> String;
    -    /// lower any low quality base to a zero and "N"
    +    /// lower any low quality base to a zero and "N"
         fn lower_ambiguity_q(&mut self) -> ();
         /// Trim sequences based on quality
         fn trim(&mut self)  -> ();
    @@ -312,9 +314,9 @@
         fn new (id: &String, seq: &String, qual: &String) -> Seq{
             let id_copy = Self::sanitize_id(&id);
             let mut thresholds = HashMap::new();
    -        thresholds.insert("min_avg_qual".to_string(),20.0);
    -        thresholds.insert("min_length".to_string(),100.0);
    -        thresholds.insert("min_trim_qual".to_string(),20.0);
    +        thresholds.insert("min_avg_qual".to_string(),20.0);
    +        thresholds.insert("min_length".to_string(),100.0);
    +        thresholds.insert("min_trim_qual".to_string(),20.0);
     
             return Seq{
                 id:     id_copy,
    @@ -339,14 +341,14 @@
         /// TODO make it more like the careful method than quick.
         fn from_string (seq_str: &String) -> Seq {
             let mut lines = seq_str.lines();
    -        let id = lines.next().expect("Could not parse ID");
    -        let seq = lines.next().expect("Could not parse sequence");
    -        lines.next().expect("Could not parse +");
    +        let id = lines.next().expect("Could not parse ID");
    +        let seq = lines.next().expect("Could not parse sequence");
    +        lines.next().expect("Could not parse +");
             let qual_opt = lines.next();
             if qual_opt == None {
                 return Seq::blank();
             }
    -        let qual = qual_opt.expect("Could not read the qual line");
    +        let qual = qual_opt.expect("Could not read the qual line");
     
             // TODO try to guess the pair ID, e.g., replace /1 with /2
     
    @@ -366,7 +368,7 @@
                 return String::new();
             }
             let mut id_copy = id.clone();
    -        if id_copy.chars().nth(0).expect("ID was empty") == '@' {
    +        if id_copy.chars().nth(0).expect("ID was empty") == '@' {
                 id_copy.pop();
             }
             return id_copy;
    @@ -382,7 +384,7 @@
             // First find the indices b/c it is so slow to
             // edit a string in-place one char at a time.
             for (i,nt) in self.seq.chars().enumerate(){
    -            if nt == 'N' || nt == 'n' || self.qual.chars().nth(i).expect("Expected a char") < low_score {
    +            if nt == 'N' || nt == 'n' || self.qual.chars().nth(i).expect("Expected a char") < low_score {
                     low_qual_idx[i] = true;
                 }
             }
    @@ -391,7 +393,7 @@
             let mut new_qual=String::new();
             for (i,nt) in self.seq.chars().enumerate(){
                 if low_qual_idx[i] {
    -                new_seq.push('N');
    +                new_seq.push('N');
                     new_qual.push(zero_score);
                 } else{
                     new_seq.push(nt);
    @@ -405,13 +407,13 @@
     
         /// Trim the ends of reads with low quality
         fn trim(&mut self) {
    -        let min_qual = *self.thresholds.entry("min_trim_qual".to_string())
    +        let min_qual = *self.thresholds.entry("min_trim_qual".to_string())
                 .or_insert(0.0) as u8;
     
             let mut trim5=0;
             let mut trim3=&self.qual.len()-0;
             
    -        // 5'
    +        // 5'
             for qual in self.qual.chars(){
                 if qual as u8 - 33 < min_qual {
                     trim5+=1;
    @@ -420,7 +422,7 @@
                 }
             }
     
    -        // 3'
    +        // 3'
             for qual in self.qual.chars().rev() {
                 if qual as u8  - 33 < min_qual {
                     trim3-=1;
    @@ -441,7 +443,7 @@
         /// Reports bool whether the read passes thresholds.
         fn is_high_quality(&mut self) -> bool {
             // fail if seq len is short
    -        let min_length = self.thresholds.get(&"min_length".to_string()).expect("min_length does not look like a number");
    +        let min_length = self.thresholds.get(&"min_length".to_string()).expect("min_length does not look like a number");
             let seq_len = self.seq.len() as f32;
             if seq_len < *min_length {
                 //.parse::<i32>().unwrap();
    @@ -455,7 +457,7 @@
     
             // fail if qual is low
             let avg_qual = (total_qual as f32/seq_len) - 33.0;
    -        let min_qual = self.thresholds.get(&"min_avg_qual".to_string()).expect("min_avg_qual does not look like a number");
    +        let min_qual = self.thresholds.get(&"min_avg_qual".to_string()).expect("min_avg_qual does not look like a number");
             if avg_qual < *min_qual {
                 return false;
             }
    @@ -465,18 +467,18 @@
     
         fn to_string(&self) -> String {
             let mut entry = String::new();
    -        if self.id.len() > 0 && self.id.chars().nth(0).expect("Seq ID was not set") != '@' {
    -            entry.push('@');
    +        if self.id.len() > 0 && self.id.chars().nth(0).expect("Seq ID was not set") != '@' {
    +            entry.push('@');
             }
             entry.push_str(self.id.trim());
    -        entry.push_str("\n");
    +        entry.push_str("\n");
             entry.push_str(self.seq.trim());
    -        entry.push_str("\n+\n");
    +        entry.push_str("\n+\n");
             entry.push_str(&self.qual.trim());
             return entry;
         }
         fn print(&self) -> () {
    -        println!("{}",self.to_string());
    +        println!("{}",self.to_string());
         }
     } 
     
    diff --git a/docs/src/fasten/lib.rs.html b/docs/src/fasten/lib.rs.html
    index 2fcd3742..45151a19 100644
    --- a/docs/src/fasten/lib.rs.html
    +++ b/docs/src/fasten/lib.rs.html
    @@ -1,4 +1,6 @@
    -lib.rs - source
    1
    +lib.rs - source
    +    
    1
     2
     3
     4
    @@ -162,6 +164,33 @@
     162
     163
     164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +183
    +184
    +185
    +186
    +187
    +188
    +189
    +190
    +191
     
    //! Perform random operations on fastq files, using unix streaming.
     //! Secure your analysis with Fasten!
     //! # Synopsis
    @@ -216,12 +245,12 @@
     //!
     //! ## Validate a whole directory of fastq reads
     //! ```text
    -//! \ls *_1.fastq.gz | xargs -n 1 -P 4 bash -c '
    -//!   echo -n "." >&2 # progress bar
    +//! \ls *_1.fastq.gz | xargs -n 1 -P 4 bash -c '
    +//!   echo -n "." >&2 # progress bar
     //!   R1=$0
     //!   R2=${0/_1.fastq.gz/_2.fastq.gz}
     //!   zcat $R1 $R2 | fasten_shuffle | fasten_validate --paired-end
    -//! '
    +//! '
     //! ```
     
     extern crate regex;
    @@ -229,6 +258,7 @@
     extern crate getopts;
     use std::env;
     use std::path::Path;
    +use std::collections::HashMap;
     
     use getopts::Options;
     use getopts::Matches;
    @@ -236,31 +266,31 @@
     /// input/output methods
     pub mod io;
     
    -const VERSION: &'static str = env!("CARGO_PKG_VERSION");
    +const VERSION: &'static str = env!("CARGO_PKG_VERSION");
     
     /// Have some strings that can be printed which could be
     /// used to propagate errors between piped scripts.
     
     /// Invalid fastq ID (no @)
    -static INVALID_ID  :&'static str= "invalid_id";
    +static INVALID_ID  :&'static str= "invalid_id";
     /// Invalid sequence (underscore)
    -static INVALID_SEQ :&'static str= "invalid_seq";
    +static INVALID_SEQ :&'static str= "invalid_seq";
     /// Invalid plus line (no +)
    -static INVALID_PLUS:&'static str= "invalid_plus";
    +static INVALID_PLUS:&'static str= "invalid_plus";
     /// Invalid qual line (~ is chr 126 when the normal max number is 40)
    -static INVALID_QUAL:&'static str= "invalid_qual";
    +static INVALID_QUAL:&'static str= "invalid_qual";
     
     /// Propagate an error by printing invalid read(s)
     pub fn eexit() -> () {
    -    println!("{}\n{}\n{}\n{}",INVALID_ID,INVALID_SEQ,INVALID_PLUS,INVALID_QUAL);
    +    println!("{}\n{}\n{}\n{}",INVALID_ID,INVALID_SEQ,INVALID_PLUS,INVALID_QUAL);
         std::process::exit(1);
     }
     
    -/// Rewrite print!() so that it doesn't panic on broken
    +/// Rewrite print!() so that it doesn't panic on broken
     /// pipe.
     #[macro_export]
     macro_rules! print (
    -    // The extra scope is necessary so we don't leak imports
    +    // The extra scope is necessary so we don't leak imports
         ($($arg:tt)*) => ({
             // The `write!()` macro is written so it can use `std::io::Write`
             // or `std::fmt::Write`, this import sets which to use
    @@ -276,35 +306,35 @@
     /// a function that reads an options object and adds fasten default options.
     pub fn fasten_base_options() -> Options{
         let mut opts = Options::new();
    -    opts.optflag("h", "help", "Print this help menu.");
    -    opts.optopt("n","numcpus","Number of CPUs (default: 1)","INT");
    -    opts.optflag("p","paired-end","The input reads are interleaved paired-end");
    -    opts.optflag("","verbose","Print more status messages");
    -    opts.optflag("","version","Print the version of Fasten and exit");
    +    opts.optflag("h", "help", "Print this help menu.");
    +    opts.optopt("n","numcpus","Number of CPUs (default: 1)","INT");
    +    opts.optflag("p","paired-end","The input reads are interleaved paired-end");
    +    opts.optflag("","verbose","Print more status messages");
    +    opts.optflag("","version","Print the version of Fasten and exit");
     
         return opts;
     }
     
     /// a function that processes the options on the command line
     /// The brief is a str that describes the program without using the program
    -/// name, e.g., "counts kmers" for fasten_kmer.
    +/// name, e.g., "counts kmers" for fasten_kmer.
     /// This function also takes care of --version.
     /// If --help is invoked, then the program name, the brief, and the usage()
     /// are all printed to stdout and then the program exits with 0.
     // TODO if possible add in default somehow for numcpus
     pub fn fasten_base_options_matches(brief:&str, opts:Options) -> Matches{
         let args: Vec<String> = env::args().collect();
    -    let matches = opts.parse(&args[1..]).expect("ERROR: could not parse parameters");
    +    let matches = opts.parse(&args[1..]).expect("ERROR: could not parse parameters");
     
    -    if matches.opt_present("version") {
    -        println!("Fasten v{}", &VERSION);
    +    if matches.opt_present("version") {
    +        println!("Fasten v{}", &VERSION);
             std::process::exit(0);
         }
    -    if matches.opt_present("h") {
    +    if matches.opt_present("h") {
             let prog_name = Path::new(&args[0])
                 .file_stem().unwrap()
                 .to_str().unwrap();
    -        println!("{}: {}\n\n{}", 
    +        println!("{}: {}\n\n{}", 
                 &prog_name,
                 &brief,
                 &opts.usage(
    @@ -323,7 +353,33 @@
         // is there a better way to get the basename of the program???
         let program = Path::file_name(Path::new(&args[0])).unwrap().to_str().unwrap();
         let str_ref = stringlike.as_ref();
    -    eprintln!("{}: {}", &program, str_ref);
    +    eprintln!("{}: {}", &program, str_ref);
    +}
    +
    +/// Reverse complement a DNA sequence.
    +/// Take into account lowercase vs uppercase.
    +/// Ambiguity codes are also handled.
    +pub fn reverse_complement(dna: &str) -> String {
    +    // Create a mapping for complement bases, including ambiguity codes.
    +    let complement_map: HashMap<char, char> = [
    +        ('A', 'T'), ('T', 'A'), ('G', 'C'), ('C', 'G'),
    +        ('R', 'Y'), ('Y', 'R'), ('S', 'S'), ('W', 'W'),
    +        ('K', 'M'), ('M', 'K'), ('B', 'V'), ('V', 'B'),
    +        ('D', 'H'), ('H', 'D'), ('N', 'N'),
    +        ('a', 't'), ('t', 'a'), ('g', 'c'), ('c', 'g'),
    +        ('r', 'y'), ('y', 'r'), ('s', 's'), ('w', 'w'),
    +        ('k', 'm'), ('m', 'k'), ('b', 'v'), ('v', 'b'),
    +        ('d', 'h'), ('h', 'd'), ('n', 'n'),
    +    ]
    +    .iter()
    +    .cloned()
    +    .collect();
    +
    +    // Generate the reverse complement.
    +    dna.chars()
    +        .rev()
    +        .map(|base| complement_map.get(&base).cloned().unwrap_or('N')) // Default to 'N' for unknown bases.
    +        .collect()
     }
     
     
    \ No newline at end of file diff --git a/docs/src/fasten_clean/fasten_clean.rs.html b/docs/src/fasten_clean/fasten_clean.rs.html index 9bba159a..6f606d42 100644 --- a/docs/src/fasten_clean/fasten_clean.rs.html +++ b/docs/src/fasten_clean/fasten_clean.rs.html @@ -1,4 +1,6 @@ -fasten_clean.rs - source
    1
    +fasten_clean.rs - source
    +    
    1
     2
     3
     4
    @@ -237,50 +239,50 @@
         let mut opts = fasten_base_options();
     
         // script-specific options
    -    opts.optopt("","min-length","Minimum length for each read in bp","INT");
    -    opts.optopt("","min-avg-quality","Minimum average quality for each read","FLOAT");
    -    opts.optopt("","min-trim-quality","Trim the edges of each read until a nucleotide of at least X quality is found","INT");
    +    opts.optopt("","min-length","Minimum length for each read in bp","INT");
    +    opts.optopt("","min-avg-quality","Minimum average quality for each read","FLOAT");
    +    opts.optopt("","min-trim-quality","Trim the edges of each read until a nucleotide of at least X quality is found","INT");
     
    -    let matches = fasten_base_options_matches("Trims and filters reads", opts);
    +    let matches = fasten_base_options_matches("Trims and filters reads", opts);
     
         let mut min_length :usize = 0;
    -    if matches.opt_present("min-length") {
    -        min_length = matches.opt_str("min-length")
    -            .expect("ERROR: could not read the minimum length parameter")
    +    if matches.opt_present("min-length") {
    +        min_length = matches.opt_str("min-length")
    +            .expect("ERROR: could not read the minimum length parameter")
                 .parse()
    -            .expect("ERROR: min-length is not an integer");
    +            .expect("ERROR: min-length is not an integer");
         }
     
         let mut min_avg_qual :f32 = 0.0;
    -    if matches.opt_present("min-avg-quality") {
    -        min_avg_qual = matches.opt_str("min-avg-quality")
    -            .expect("ERROR: could not read the minimum average quality parameter")
    +    if matches.opt_present("min-avg-quality") {
    +        min_avg_qual = matches.opt_str("min-avg-quality")
    +            .expect("ERROR: could not read the minimum average quality parameter")
                 .parse()
    -            .expect("ERROR: min-avg-qual is not an integer");
    +            .expect("ERROR: min-avg-qual is not an integer");
         }
     
         let mut min_trim_qual :u8 = 0;
    -    if matches.opt_present("min-trim-quality") {
    -        min_trim_qual = matches.opt_str("min-trim-quality")
    -            .expect("ERROR: could not read the minimum trim quality parameter")
    +    if matches.opt_present("min-trim-quality") {
    +        min_trim_qual = matches.opt_str("min-trim-quality")
    +            .expect("ERROR: could not read the minimum trim quality parameter")
                 .parse()
    -            .expect("ERROR: min-trim-qual is not an integer");
    +            .expect("ERROR: min-trim-qual is not an integer");
         }
     
    -    let paired_end:bool = matches.opt_present("paired-end");
    +    let paired_end:bool = matches.opt_present("paired-end");
     
         let _num_cpus:usize = {
    -        if matches.opt_present("numcpus") {
    -            matches.opt_str("numcpus").expect("ERROR parsing --numcpus")
    +        if matches.opt_present("numcpus") {
    +            matches.opt_str("numcpus").expect("ERROR parsing --numcpus")
                     .parse()
    -                .expect("ERROR: numcpus is not an integer")
    +                .expect("ERROR: numcpus is not an integer")
             } else {
                 1
             }
         };
     
         // Read the file and send seqs to threads
    -    let my_file = File::open("/dev/stdin").expect("Could not open file");
    +    let my_file = File::open("/dev/stdin").expect("Could not open file");
         let my_buffer=BufReader::new(my_file);
         let fastq_reader = fastq::FastqReader::new(my_buffer);
         let fastq_iter = fastq_reader.into_iter();
    @@ -314,7 +316,7 @@
     
             if passed {
                 for i in 0..trimmed_seqs.len() {
    -                println!("{}\n{}\n+\n{}",
    +                println!("{}\n{}\n+\n{}",
                              &trimmed_ids[i],
                              &trimmed_seqs[i],
                              &trimmed_quals[i],
    @@ -332,7 +334,7 @@
     }
     
     /// Determine average quality of a qual cigar string,
    -/// e.g., let q:f32 = avg_quality("AABC!...")
    +/// e.g., let q:f32 = avg_quality("AABC!...")
     fn avg_quality(qual: &String) -> f32 {
         let mut total :u32 = 0;
         for qual_char in qual.chars() {
    @@ -349,7 +351,7 @@
     
         let offset_min_qual = min_qual + 33;
         
    -    // 5'
    +    // 5'
         for qual in qual.chars(){
             if (qual as u8) < offset_min_qual {
                 trim5+=1;
    @@ -358,7 +360,7 @@
             }
         }
     
    -    // 3'
    +    // 3'
         for qual in qual.chars().rev() {
             if (qual as u8) < offset_min_qual {
                 trim3-=1;
    diff --git a/docs/src/fasten_combine/fasten_combine.rs.html b/docs/src/fasten_combine/fasten_combine.rs.html
    index 0178aab2..b78d9f6d 100644
    --- a/docs/src/fasten_combine/fasten_combine.rs.html
    +++ b/docs/src/fasten_combine/fasten_combine.rs.html
    @@ -1,4 +1,6 @@
    -fasten_combine.rs - source
    1
    +fasten_combine.rs - source
    +    
    1
     2
     3
     4
    @@ -324,7 +326,7 @@
     //!        --min-qual-char CHAR
     //!                        Minimum quality character (default: !)
     //!
    -//!    NOTE: range of quality scores is !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHI
    +//!    NOTE: range of quality scores is !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHI
     //!```
     
     extern crate fasten;
    @@ -350,14 +352,14 @@
     const TEN: f32 = 10.0;
     /// Glues together paired end reads internally and is a
     /// character not expected in any read
    -const READ_SEPARATOR :char = '~';
    +const READ_SEPARATOR :char = '~';
     
     fn main(){
         let mut opts = fasten_base_options();
     
    -    // make a string of characters like !"#...GHI to represent all quals
    -    let default_phred_min_char:char = '!';
    -    let default_phred_max_char:char = 'I';
    +    // make a string of characters like !"#...GHI to represent all quals
    +    let default_phred_min_char:char = '!';
    +    let default_phred_max_char:char = 'I';
         let default_phred_min:u8 = default_phred_min_char as u8 - 33;
         let default_phred_max:u8 = default_phred_max_char as u8 - 33;
         let mut qual_range_string = String::with_capacity((default_phred_max - default_phred_min + 1) as usize);
    @@ -366,28 +368,28 @@
         }
     
     
    -    opts.optopt("","max-qual-char",
    -      format!("Maximum quality character (default: {})", default_phred_max_char).as_str(),
    -      "CHAR");
    -    opts.optopt("","min-qual-char",
    -      format!("Minimum quality character (default: {})", default_phred_min_char).as_str(),
    -      "CHAR");
    +    opts.optopt("","max-qual-char",
    +      format!("Maximum quality character (default: {})", default_phred_max_char).as_str(),
    +      "CHAR");
    +    opts.optopt("","min-qual-char",
    +      format!("Minimum quality character (default: {})", default_phred_min_char).as_str(),
    +      "CHAR");
     
    -    let description:String = format!("Collapse identical reads into single reads, recalculating quality values. If paired end, then each set of reads must be identical to be collapsed. Warning: due to multiple reads collapsing into one, read identifiers will be reconstituted. NOTE: range of quality scores is {}", qual_range_string);
    +    let description:String = format!("Collapse identical reads into single reads, recalculating quality values. If paired end, then each set of reads must be identical to be collapsed. Warning: due to multiple reads collapsing into one, read identifiers will be reconstituted. NOTE: range of quality scores is {}", qual_range_string);
         let matches = fasten_base_options_matches(&description, opts);
     
    -    let max_qual_char:char = matches.opt_default("max-qual-char", &default_phred_max_char.to_string())
    +    let max_qual_char:char = matches.opt_default("max-qual-char", &default_phred_max_char.to_string())
                          .unwrap_or(String::from(default_phred_max_char))
                          .parse()
    -                     .expect("ERROR converting --max-qual-int value to integer");
    +                     .expect("ERROR converting --max-qual-int value to integer");
     
         let mut min_qual_char:char =
    -          matches.opt_default("min-qual-char", &default_phred_min_char.to_string())
    +          matches.opt_default("min-qual-char", &default_phred_min_char.to_string())
                          .unwrap_or(String::from(default_phred_min_char))
                          .parse()
    -                     .expect("ERROR converting --min-qual-int value to integer");
    +                     .expect("ERROR converting --min-qual-int value to integer");
         if min_qual_char < default_phred_min_char {
    -      logmsg("--min-qual-char was less than the default minimum and so it will be set to the default");
    +      logmsg("--min-qual-char was less than the default minimum and so it will be set to the default");
           min_qual_char = default_phred_min_char;
         }
     
    @@ -395,10 +397,10 @@
         let min_qual:u8 = min_qual_char as u8;
         let max_qual:u8 = max_qual_char as u8;
     
    -    let paired_end = matches.opt_present("paired-end");
    +    let paired_end = matches.opt_present("paired-end");
         let _num_cpus:usize = {
    -      if matches.opt_present("numcpus") {
    -        logmsg("Warning: This script does not make use of --numcpus");
    +      if matches.opt_present("numcpus") {
    +        logmsg("Warning: This script does not make use of --numcpus");
             1 as usize
           } else {
             1 as usize
    @@ -412,7 +414,7 @@
     
         let parser = Parser::new(stdin());
         let mut parser_getter = parser.ref_iter();
    -    parser_getter.advance().expect("Could not read the first fastq entry");
    +    parser_getter.advance().expect("Could not read the first fastq entry");
         while let Some(record1) = parser_getter.get() {
             let mut id:Vec<u8>     = record1.head().to_vec();
             let mut seq:Vec<u8>    = record1.seq().to_vec(); 
    @@ -422,10 +424,10 @@
               match parser_getter.advance() {
                 Ok(_) => {},
                 Err(err) => {
    -              panic!("ERROR: could not read the second entry in a paired end read: {}", err);
    +              panic!("ERROR: could not read the second entry in a paired end read: {}", err);
                 }
               };
    -          let record2 = &parser_getter.get().expect("ERROR parsing second pair in a paired end read");
    +          let record2 = &parser_getter.get().expect("ERROR parsing second pair in a paired end read");
               let id2:&[u8]  = record2.head();
               let seq2:&[u8] = record2.seq();
               let qual2:&[u8]= record2.qual();
    @@ -440,28 +442,28 @@
               seq.extend_from_slice(seq2);
               qual.extend_from_slice(qual2);
             }
    -        //println!("{:?}", qual);
    +        //println!("{:?}", qual);
     
             // Keep track of the counts of identical sequence
             let seq_string:String = String::from(
                                        std::str::from_utf8(&seq[..])
    -                                   .expect("ERROR converting slice to str")
    +                                   .expect("ERROR converting slice to str")
                                     );
             /*
             let id_string:String = String::from(
                                       std::str::from_utf8(&id[..])
    -                                 .expect("ERROR converting slice to str")
    +                                 .expect("ERROR converting slice to str")
                                    );
             */
             let count = seq_count.entry(seq_string.clone()).or_insert(0);
             *count += 1 as u32;
     
    -        // If this sequence hasn't been seen yet,
    +        // If this sequence hasn't been seen yet,
             // then instantiate the probabilities.
             if !seq_error_rate.contains_key(&seq_string) {
                 let mut qual_vec:Vec<f32> = vec![];
                 for q in qual {
    -                // Don't mess with the read separator character
    +                // Don't mess with the read separator character
                     if q == READ_SEPARATOR as u8 {
                       qual_vec.push(q as u8 as f32);
                       continue;
    @@ -472,7 +474,7 @@
                 }
                 seq_error_rate.insert(seq_string.clone(), qual_vec);
             }
    -        //println!("{:?}", seq_error_rate.entry(seq_string));
    +        //println!("{:?}", seq_error_rate.entry(seq_string));
             
             // If this sequence has been seen yet, then
             // start combining the error rates.
    @@ -481,7 +483,7 @@
                 let qual_vec = seq_error_rate.entry(seq_string.clone()).or_insert(Vec::new());
     
                 let these_errors = qual.into_iter().map(|qual_char|{
    -                // Don't mess with the read separator character
    +                // Don't mess with the read separator character
                     if qual_char == READ_SEPARATOR as u8 {
                       return qual_char as u8 as f32;
                     }
    @@ -502,7 +504,7 @@
         let mut seq_counter=0;
         for (seq,combined_qual) in seq_error_rate {
             seq_counter += 1;
    -        //println!("{:?}", seq);continue;
    +        //println!("{:?}", seq);continue;
     
             // TODO take care of PE reads
     
    @@ -529,15 +531,15 @@
     
             if paired_end {
                 // split the seq and qual for paired end
    -            let separator_pos = seq.find(READ_SEPARATOR).expect("ERROR finding read separator");
    +            let separator_pos = seq.find(READ_SEPARATOR).expect("ERROR finding read separator");
                 let r1_seq = seq[0..separator_pos].to_string();
                 let r2_seq = seq[separator_pos+1..].to_string();
                 let r1_qual= qual_cigar[0..separator_pos].to_string();
                 let r2_qual= qual_cigar[separator_pos+1..].to_string();
    -            println!("@{}/1\n{}\n+\n{}",seq_counter,r1_seq,r1_qual);
    -            println!("@{}/2\n{}\n+\n{}",seq_counter,r2_seq,r2_qual);
    +            println!("@{}/1\n{}\n+\n{}",seq_counter,r1_seq,r1_qual);
    +            println!("@{}/2\n{}\n+\n{}",seq_counter,r2_seq,r2_qual);
             } else {
    -            println!("@{}\n{}\n+\n{}",seq_counter,seq,qual_cigar);
    +            println!("@{}\n{}\n+\n{}",seq_counter,seq,qual_cigar);
             }
         }
     }
    @@ -548,18 +550,18 @@
     /// from vector two.
     fn combine_error_vectors(errors1 :&Vec<f32>, errors2: &Vec<f32>) -> Vec<f32> {
         if errors1.len() != errors2.len() {
    -        panic!("Lengths of error vectors do not match: {} and {}", errors1.len(), errors2.len());
    +        panic!("Lengths of error vectors do not match: {} and {}", errors1.len(), errors2.len());
         }
         let mut errors_iter2=errors2.iter();
         let mut new_errors :Vec<f32> = Vec::new(); // TODO set length/capacity to errors.len()
         for p1 in errors1 {
    -        let p2 = errors_iter2.next().expect("ERROR: could not get the error probability from the second read");
    +        let p2 = errors_iter2.next().expect("ERROR: could not get the error probability from the second read");
             new_errors.push(p1 * p2);
         }
         return new_errors;
     }
     
    -// TODO a function that returns the 'min-seq' which is the
    +// TODO a function that returns the 'min-seq' which is the
     // sequence that comes first alphabetically when compared
     // with its revcom
     
    @@ -568,8 +570,8 @@
     fn recalculate_qual(qual_str: &str, count: u32) -> String {
         let mut qual_out = String::new();
     
    -    let max_qual = 'I' as u8;
    -    let min_qual = '!' as u8;
    +    let max_qual = 'I' as u8;
    +    let min_qual = '!' as u8;
     
         let qual = qual_str.to_string();
         for qual_char in qual.chars() {
    @@ -586,11 +588,11 @@
             // switch to u8 and then the corresponding char
             let mut qual_recalc_char = qual_recalc.round() as u8 as char;
             if (qual_recalc_char as u8) > max_qual {
    -            qual_recalc_char = 'I';
    +            qual_recalc_char = 'I';
             }
             // a reduction in quality is not expected... but just in case.
             if (qual_recalc_char as u8) < min_qual {
    -            qual_recalc_char = '!';
    +            qual_recalc_char = '!';
             }
             qual_out.push(qual_recalc_char);
         }
    diff --git a/docs/src/fasten_convert/fasten_convert.rs.html b/docs/src/fasten_convert/fasten_convert.rs.html
    index 904ef50d..76b5d8a7 100644
    --- a/docs/src/fasten_convert/fasten_convert.rs.html
    +++ b/docs/src/fasten_convert/fasten_convert.rs.html
    @@ -1,4 +1,6 @@
    -fasten_convert.rs - source
    1
    +fasten_convert.rs - source
    +    
    1
     2
     3
     4
    @@ -390,10 +392,10 @@
       }
       /// Return a formatted string as a fastq entry
       fn as_fastq(&self) -> String {
    -    let mut entry:String = format!("@{}\n{}\n+\n{}",
    +    let mut entry:String = format!("@{}\n{}\n+\n{}",
                                  self.id1, self.seq1, self.qual1);
         if !self.id2.is_empty() {
    -      entry = format!("{}\n@{}\n{}\n+\n{}",
    +      entry = format!("{}\n@{}\n{}\n+\n{}",
                     entry, self.id2, self.seq2, self.qual2);
         }
         return entry;
    @@ -401,10 +403,10 @@
     
       /// Return a formatted string as a fasta entry
       fn as_fasta(&self) -> String {
    -    let mut entry:String = format!(">{}\n{}",
    +    let mut entry:String = format!(">{}\n{}",
                                  self.id1, self.seq1);
         if !self.id2.is_empty() {
    -      entry = format!("{}\n>{}\n{}",
    +      entry = format!("{}\n>{}\n{}",
                     entry, self.id2, self.seq2);
         }
         return entry;
    @@ -412,16 +414,16 @@
     
       /// Return a formatted string as a sam entry
       fn as_sam(&self) -> String {
    -    let mut flag = "4"; // unmapped
    +    let mut flag = "4"; // unmapped
     
         if !self.id2.is_empty() {
    -      flag = "77"; // unmapped + pair unmapped + has pair + first in pair
    +      flag = "77"; // unmapped + pair unmapped + has pair + first in pair
         }
     
    -    let mut entry:String = vec![self.id1.as_str(), flag, "*", "0", "0", "*", "*", "0", "0", self.seq1.as_str(), self.qual1.as_str()].join("\t");
    +    let mut entry:String = vec![self.id1.as_str(), flag, "*", "0", "0", "*", "*", "0", "0", self.seq1.as_str(), self.qual1.as_str()].join("\t");
         if !self.id2.is_empty() {
    -      let entry2:String  = vec![self.id2.as_str(), "141", "*", "0", "0", "*", "*", "0", "0", self.seq2.as_str(), self.qual2.as_str()].join("\t");
    -      entry = format!("{}\n{}", entry, entry2);
    +      let entry2:String  = vec![self.id2.as_str(), "141", "*", "0", "0", "*", "*", "0", "0", self.seq2.as_str(), self.qual2.as_str()].join("\t");
    +      entry = format!("{}\n{}", entry, entry2);
         }
     
         return entry;
    @@ -435,27 +437,27 @@
         let (tx, rx):(std::sync::mpsc::Sender<FastenSeq>,std::sync::mpsc::Receiver<FastenSeq>) = channel();
         read_fastq(tx.clone(), false);
     
    -    //assert_eq!(obs_fasta_string, expected_fasta_string, "Convert fastq=>fasta");
    -    //assert_eq!(obs_sam_string, expected_sam_string, "Convert fastq=>sam");
    -    //assert_eq!(obs_fastq_string, expected_fastq_string, "Convert fastq=>fastq (self to self)");
    +    //assert_eq!(obs_fasta_string, expected_fasta_string, "Convert fastq=>fasta");
    +    //assert_eq!(obs_sam_string, expected_sam_string, "Convert fastq=>sam");
    +    //assert_eq!(obs_fastq_string, expected_fastq_string, "Convert fastq=>fastq (self to self)");
     }
     */
           
     fn main(){
         let mut opts = fasten_base_options();
    -    opts.optopt("i", "in-format",  "The input format for stdin. FORMAT can be: fastq, fasta, sam.",  "FORMAT");
    -    opts.optopt("o", "out-format", "The output format for stdin. See --in-format for FORMAT options.", "FORMAT");
    +    opts.optopt("i", "in-format",  "The input format for stdin. FORMAT can be: fastq, fasta, sam.",  "FORMAT");
    +    opts.optopt("o", "out-format", "The output format for stdin. See --in-format for FORMAT options.", "FORMAT");
     
    -    let description:String = format!("Converts between sequence formats.");
    +    let description:String = format!("Converts between sequence formats.");
         let matches = fasten_base_options_matches(&description, opts);
     
    -    let paired_end = matches.opt_present("paired-end");
    +    let paired_end = matches.opt_present("paired-end");
     
    -    let in_format  = matches.opt_default("in-format", "fastq")
    -                       .unwrap_or(String::from("fastq"))
    +    let in_format  = matches.opt_default("in-format", "fastq")
    +                       .unwrap_or(String::from("fastq"))
                            .to_lowercase();
    -    let out_format = matches.opt_default("out-format","fastq")
    -                       .unwrap_or(String::from("fastq"))
    +    let out_format = matches.opt_default("out-format","fastq")
    +                       .unwrap_or(String::from("fastq"))
                            .to_lowercase();
     
         let (tx, rx):(std::sync::mpsc::Sender<FastenSeq>,std::sync::mpsc::Receiver<FastenSeq>) = channel();
    @@ -464,27 +466,27 @@
     
         //TODO (?) multithread this 
         match in_format.as_str() {
    -      "fastq" => {read_fastq(tx, paired_end);}
    -      "sam"   => {read_sam(tx, paired_end);}
    -      "fasta" => {read_fasta(tx, paired_end);}
    -      _ => {panic!("Unknown input format {}", in_format);}
    +      "fastq" => {read_fastq(tx, paired_end);}
    +      "sam"   => {read_sam(tx, paired_end);}
    +      "fasta" => {read_fasta(tx, paired_end);}
    +      _ => {panic!("Unknown input format {}", in_format);}
         };
     
         match out_format.as_str() {
    -      "fastq" => {write_fastq(rx);}
    -      "fasta" => {write_fasta(rx);}
    -      "sam"   => {write_sam(rx);}
    -      _ => {panic!("Unknown output format {}", out_format);}
    +      "fastq" => {write_fastq(rx);}
    +      "fasta" => {write_fasta(rx);}
    +      "sam"   => {write_sam(rx);}
    +      _ => {panic!("Unknown output format {}", out_format);}
         };
     
     }
     
    -// I wasn't satisfied with the existing fasta parsers and how they might
    +// I wasn't satisfied with the existing fasta parsers and how they might
     // read stdin and so I rolled out my own
     /// Read fasta from stdin and transmit it to a channel
     fn read_fasta(tx:std::sync::mpsc::Sender<FastenSeq>, paired_end:bool){
         if paired_end {
    -        logmsg("--paired-end was given but it is ignored in a fasta context");
    +        logmsg("--paired-end was given but it is ignored in a fasta context");
         }
     
         // Read the fasta through stdin
    @@ -496,12 +498,12 @@
         let bytes = stdin.read_line(&mut seq.id1).unwrap();
         seq.id1 = seq.id1.trim().to_string();
         if bytes == 0 {
    -        panic!("Zero byte stdin");
    +        panic!("Zero byte stdin");
         }
    -    // remove ">"
    +    // remove ">"
         let gt_sign = seq.id1.remove(0);
    -    if gt_sign != '>' {
    -        panic!("ERROR: first character of first line of stdin is not '>' as expected. Found {}", gt_sign);
    +    if gt_sign != '>' {
    +        panic!("ERROR: first character of first line of stdin is not '>' as expected. Found {}", gt_sign);
         }
     
         loop{
    @@ -512,29 +514,29 @@
             if bytes == 0 {
                 // Send the last sequence
                 // The quality line will be fake and as long as the sequence length
    -            seq.qual1 = (0..seq.seq1.len()).map(|_| "I").collect::<String>();
    -            tx.send(seq).expect("Sending seq object to writer");
    +            seq.qual1 = (0..seq.seq1.len()).map(|_| "I").collect::<String>();
    +            tx.send(seq).expect("Sending seq object to writer");
                 break;
             }
    -        // if we're looking at the next sequence identifier,
    +        // if we're looking at the next sequence identifier,
             // send off the current sequence and start fresh with
             // the new identifier.
    -        else if &buffer[0..1]==">" {
    +        else if &buffer[0..1]==">" {
                 // The quality line will be fake and as long as the sequence length
    -            seq.qual1 = (0..seq.seq1.len()).map(|_| "I").collect::<String>();
    +            seq.qual1 = (0..seq.seq1.len()).map(|_| "I").collect::<String>();
                 // Send off the sequence
    -            tx.send(seq).expect("Sending seq object to writer");
    +            tx.send(seq).expect("Sending seq object to writer");
     
                 seq = FastenSeq::new();
                 seq.id1 = buffer;
    -            // remove ">"
    +            // remove ">"
                 let gt_sign = seq.id1.remove(0);
    -            if gt_sign != '>' {
    -                panic!("ERROR: first character of first line of stdin is not '>' as expected. Found {}", gt_sign);
    +            if gt_sign != '>' {
    +                panic!("ERROR: first character of first line of stdin is not '>' as expected. Found {}", gt_sign);
                 }
             }
             else {
    -            seq.seq1 = format!("{}{}", seq.seq1, buffer);
    +            seq.seq1 = format!("{}{}", seq.seq1, buffer);
             }
         }
     
    @@ -543,12 +545,12 @@
     /// Read sam from stdin and transmit it to a channel
     fn read_sam(tx:std::sync::mpsc::Sender<FastenSeq>, paired_end:bool){
       if paired_end {
    -    logmsg("--paired-end given but paired-endedness will be determined by sam format flags");
    +    logmsg("--paired-end given but paired-endedness will be determined by sam format flags");
       }
     
       // TODO check if sorted by name so that the pairs are next to each other
     
    -  let mut reader = bam::SamReader::from_path("/dev/stdin").unwrap();
    +  let mut reader = bam::SamReader::from_path("/dev/stdin").unwrap();
       let mut r      = bam::Record::new();
     
       loop {
    @@ -557,7 +559,7 @@
         match reader.read_into(&mut r) {
           Ok(false) => break,
           Ok(true)  => {},
    -      Err(e)    => panic!("{}", e),
    +      Err(e)    => panic!("{}", e),
         }
         seq.id1    = String::from(std::str::from_utf8(r.name()).unwrap());
         seq.seq1   = String::from_utf8(r.sequence().to_vec()).unwrap();
    @@ -568,14 +570,14 @@
           match reader.read_into(&mut r) {
             Ok(false) => break,
             Ok(true)  => {},
    -        Err(e)    => panic!("{}", e),
    +        Err(e)    => panic!("{}", e),
           }
           seq.id2    = String::from(std::str::from_utf8(r.name()).unwrap());
           seq.seq2   = String::from_utf8(r.sequence().to_vec()).unwrap();
           seq.qual2  = String::from_utf8(r.qualities().to_readable()).unwrap();
         }
     
    -    tx.send(seq).expect("Sending seq object to writer");
    +    tx.send(seq).expect("Sending seq object to writer");
       }
     }
     
    @@ -585,7 +587,7 @@
       let parser = Parser::new(stdin());
     
       let mut parser_getter = parser.ref_iter();
    -  parser_getter.advance().expect("Could not read the first fastq entry");
    +  parser_getter.advance().expect("Could not read the first fastq entry");
       while let Some(record1) = parser_getter.get() {
         let mut seq:FastenSeq = FastenSeq::new();
         seq.id1   = std::str::from_utf8(record1.head()).unwrap().to_string();
    @@ -596,16 +598,16 @@
           match &parser_getter.advance() {
             Ok(_) => {},
             Err(err) => {
    -          panic!("ERROR: could not read the second entry in a paired end read: {}", err);
    +          panic!("ERROR: could not read the second entry in a paired end read: {}", err);
             }
           };
    -      let record2 = &parser_getter.get().expect("ERROR parsing second pair in a paired end read");
    +      let record2 = &parser_getter.get().expect("ERROR parsing second pair in a paired end read");
           seq.id2   = std::str::from_utf8(record2.head()).unwrap().to_string();
           seq.seq2  = std::str::from_utf8(record2.seq()).unwrap().to_string();
           seq.qual2 = std::str::from_utf8(record2.qual()).unwrap().to_string();
         }
     
    -    tx.send(seq).expect("Sending seq object to writer");
    +    tx.send(seq).expect("Sending seq object to writer");
     
         match &parser_getter.advance() {
           Ok(_) => {},
    @@ -618,7 +620,7 @@
     fn write_fastq(rx:std::sync::mpsc::Receiver<FastenSeq>){
       let receiver = rx.iter();
       for seq in receiver {
    -    println!("{}", seq.as_fastq());
    +    println!("{}", seq.as_fastq());
       }
     }
     
    @@ -626,7 +628,7 @@
     fn write_fasta(rx:std::sync::mpsc::Receiver<FastenSeq>){
       let receiver = rx.iter();
       for seq in receiver {
    -    println!("{}", seq.as_fasta());
    +    println!("{}", seq.as_fasta());
       }
     }
     
    @@ -634,7 +636,7 @@
     fn write_sam(rx:std::sync::mpsc::Receiver<FastenSeq>){
       let receiver = rx.iter();
       for seq in receiver {
    -    println!("{}", seq.as_sam());
    +    println!("{}", seq.as_sam());
       }
     }
     
    diff --git a/docs/src/fasten_inspect/fasten_inspect.rs.html b/docs/src/fasten_inspect/fasten_inspect.rs.html
    index b16b2f63..04637dd8 100644
    --- a/docs/src/fasten_inspect/fasten_inspect.rs.html
    +++ b/docs/src/fasten_inspect/fasten_inspect.rs.html
    @@ -1,4 +1,6 @@
    -fasten_inspect.rs - source
    1
    +fasten_inspect.rs - source
    +    
    1
     2
     3
     4
    @@ -240,12 +242,12 @@
     fn main(){
         let opts = fasten_base_options();
         // Options specific to this script
    -    // opts.optflag("","paired-end","The reads are interleaved paired-end");
    +    // opts.optflag("","paired-end","The reads are interleaved paired-end");
     
    -    let matches = fasten_base_options_matches("Marks up your reads with useful information like read length", opts);
    +    let matches = fasten_base_options_matches("Marks up your reads with useful information like read length", opts);
     
         let lines_per_read :u8 ={
    -        if matches.opt_present("paired-end") {
    +        if matches.opt_present("paired-end") {
                 8
             }else{
                 4
    @@ -255,20 +257,20 @@
         // If there is a match on these, then mark invalid.
         // In other words, we are looking for a pattern that
         // is NOT the target seq or qual
    -    let seq_regex = Regex::new(r"[^a-zA-Z]").expect("malformed seq regex");
    -    //let qual_regex= Regex::new(r"[^!-Za-z]").expect("malformed qual regex");
    -    let qual_regex= Regex::new(r"\s").expect("malformed qual regex");
    +    let seq_regex = Regex::new(r"[^a-zA-Z]").expect("malformed seq regex");
    +    //let qual_regex= Regex::new(r"[^!-Za-z]").expect("malformed qual regex");
    +    let qual_regex= Regex::new(r"\s").expect("malformed qual regex");
     
         validate_reads(lines_per_read, seq_regex, qual_regex);
     
    -    if matches.opt_present("verbose") {
    -        fasten::logmsg("These reads have been validated!");
    +    if matches.opt_present("verbose") {
    +        fasten::logmsg("These reads have been validated!");
         }
     }
     
     /// marks up reads from stdin
     fn validate_reads(lines_per_read: u8, seq_regex: regex::Regex, qual_regex: regex::Regex) {
    -    let my_file = File::open("/dev/stdin").expect("Could not open file");
    +    let my_file = File::open("/dev/stdin").expect("Could not open file");
         let mut my_buffer = BufReader::new(my_file);
     
         let mut id   = String::new();
    @@ -280,43 +282,43 @@
         loop{
     
             id.clear();
    -        if my_buffer.read_line(&mut id).expect("Cannot read new line") == 0 {
    +        if my_buffer.read_line(&mut id).expect("Cannot read new line") == 0 {
                 break;
             }
     
             seq.clear();
    -        my_buffer.read_line(&mut seq).expect("ERROR: failed to read 'seq' line");
    +        my_buffer.read_line(&mut seq).expect("ERROR: failed to read 'seq' line");
             plus.clear();
    -        my_buffer.read_line(&mut plus).expect("ERROR: failed to read 'plus' line");
    +        my_buffer.read_line(&mut plus).expect("ERROR: failed to read 'plus' line");
             qual.clear();
    -        my_buffer.read_line(&mut qual).expect("ERROR: failed to read 'qual' line");
    +        my_buffer.read_line(&mut qual).expect("ERROR: failed to read 'qual' line");
             id   = id.trim().to_string();
             seq  = seq.trim().to_string();
             plus = plus.trim().to_string();
             qual = qual.trim().to_string();
     
             // Test ID
    -        if id.chars().nth(0).unwrap() == '@' {
    -            id = format!("{} id-at:1", &id);
    +        if id.chars().nth(0).unwrap() == '@' {
    +            id = format!("{} id-at:1", &id);
             } else {
    -            id = format!("{} id-at:0", &id);
    +            id = format!("{} id-at:0", &id);
             }
     
             // Test Seq
    -        id = format!("{} seq-length:{}", &id, seq.len());
    +        id = format!("{} seq-length:{}", &id, seq.len());
             let mut illegal_seq_chars:String = String::new();
             if seq_regex.is_match(&seq) {
                 for cap in seq_regex.captures_iter(&seq) {
                     illegal_seq_chars.push_str(&cap[0]);
                 }
             }
    -        id = format!("{} seq-invalid-chars:{}", &id, &illegal_seq_chars);
    +        id = format!("{} seq-invalid-chars:{}", &id, &illegal_seq_chars);
     
             // Test plus
    -        if plus.chars().nth(0).unwrap() == '+' {
    -            id = format!("{} id-plus:1", &id);
    +        if plus.chars().nth(0).unwrap() == '+' {
    +            id = format!("{} id-plus:1", &id);
             } else {
    -            id = format!("{} id-plus:0", &id);
    +            id = format!("{} id-plus:0", &id);
             }
     
             // Test qual
    @@ -326,7 +328,7 @@
                     illegal_qual_chars.push_str(&cap[0]);
                 }
             }
    -        id = format!("{} qual-invalid-chars:{}", &id, &illegal_qual_chars);
    +        id = format!("{} qual-invalid-chars:{}", &id, &illegal_qual_chars);
     
             // quality score regex
             let mut qual_total :usize = 0;
    @@ -340,18 +342,18 @@
                     qual_total as f32 / qual.len() as f32 - 33.0
                 }
             };
    -        id = format!("{} avg-qual:{:.2}", &id, avg_qual);
    -        id = format!("{} qual-length:{}", &id, qual.len());
    +        id = format!("{} avg-qual:{:.2}", &id, avg_qual);
    +        id = format!("{} qual-length:{}", &id, qual.len());
     
             let mut read_pair:u8 = ((i as u64 % lines_per_read as u64) + 1) as u8;
             if read_pair > 1 {
                 read_pair = 2;
             }
    -        id = format!("{} read-pair:{}", &id, &read_pair);
    +        id = format!("{} read-pair:{}", &id, &read_pair);
     
             i += 4;
     
    -        println!("{}\n{}\n{}\n{}", id, seq, plus, qual);
    +        println!("{}\n{}\n{}\n{}", id, seq, plus, qual);
         }
     }
     
    diff --git a/docs/src/fasten_kmer/fasten_kmer.rs.html b/docs/src/fasten_kmer/fasten_kmer.rs.html
    index 9e628244..5017abf8 100644
    --- a/docs/src/fasten_kmer/fasten_kmer.rs.html
    +++ b/docs/src/fasten_kmer/fasten_kmer.rs.html
    @@ -1,4 +1,6 @@
    -fasten_kmer.rs - source
    1
    +fasten_kmer.rs - source
    +    
    1
     2
     3
     4
    @@ -305,6 +307,68 @@
     305
     306
     307
    +308
    +309
    +310
    +311
    +312
    +313
    +314
    +315
    +316
    +317
    +318
    +319
    +320
    +321
    +322
    +323
    +324
    +325
    +326
    +327
    +328
    +329
    +330
    +331
    +332
    +333
    +334
    +335
    +336
    +337
    +338
    +339
    +340
    +341
    +342
    +343
    +344
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    +361
    +362
    +363
    +364
    +365
    +366
    +367
    +368
    +369
     
    //! Counts kmers.
     //! Each line is a kmer with two columns separated by tab: kmer, count
     //! Optional columns starting with column 3 are the reads that start with that kmer
    @@ -355,68 +419,74 @@
     extern crate fasten;
     extern crate statistical;
     extern crate getopts;
    +extern crate rand;
    +extern crate fancy_regex;
     
     use std::io::BufReader;
     use std::io::BufRead;
     use std::io::stdin;
     use std::io::Stdin;
    +use rand::Rng;
    +//use rand::seq::SliceRandom;
     
    -use fasten::fasten_base_options;
    +use fasten::fasten_base_options;
     use fasten::fasten_base_options_matches;
     use fasten::logmsg;
     
    +use fancy_regex::Regex;
    +
     use std::collections::HashMap;
     
     /// Glues together paired end reads internally and is a
     /// character not expected in any read
    -const READ_SEPARATOR :char = '~';
    +const READ_SEPARATOR :char = '~';
     
     #[test]
    -/// Let's count some kmers on homopolymers
    +/// Let's count some kmers on homopolymers
     fn test_kmer_counting_homopolymers () {
         let k = 4;
     
         // The first easy test is an AAAA kmer in a Ax10 homopolymer
    -    let a_homopolymer = (0..10).map(|_| "A").collect::<String>();
    +    let a_homopolymer = (0..10).map(|_| "A").collect::<String>();
         let mut kmer = kmers_in_str(&a_homopolymer, k, false);
    -    let obs_a_count = *kmer.entry(String::from("AAAA")).or_insert(0);
    -    assert_eq!(obs_a_count, 7, "10-mer A yields seven 4-mers of A");
    -    let obs_t_count = *kmer.entry(String::from("TTTT")).or_insert(0);
    -    assert_eq!(obs_t_count, 0, "10-mer A yields zero 4-mers of T");
    +    let obs_a_count = *kmer.entry(String::from("AAAA")).or_insert(0);
    +    assert_eq!(obs_a_count, 7, "10-mer A yields seven 4-mers of A");
    +    let obs_t_count = *kmer.entry(String::from("TTTT")).or_insert(0);
    +    assert_eq!(obs_t_count, 0, "10-mer A yields zero 4-mers of T");
     
         // Ok but what about revcom kmers
         let mut kmer = kmers_in_str(&a_homopolymer, k, true );
    -    let obs_a_count = *kmer.entry(String::from("AAAA")).or_insert(0);
    -    assert_eq!(obs_a_count, 7, "10-mer A yields seven 4-mers of A");
    -    let obs_t_count = *kmer.entry(String::from("TTTT")).or_insert(0);
    -    assert_eq!(obs_t_count, 7, "10-mer A yields seven 4-mers of T");
    +    let obs_a_count = *kmer.entry(String::from("AAAA")).or_insert(0);
    +    assert_eq!(obs_a_count, 7, "10-mer A yields seven 4-mers of A");
    +    let obs_t_count = *kmer.entry(String::from("TTTT")).or_insert(0);
    +    assert_eq!(obs_t_count, 7, "10-mer A yields seven 4-mers of T");
     }   
     #[test]
    -/// Let's count some kmers on something more complicated
    +/// Let's count some kmers on something more complicated
     fn test_kmer_counting_4mers () {
         let k = 4;
     
         // This is the first seq of the test file four_reads.fastq
    -    let seq = "AAAGTGCTCTTAACTTGTCCCGCTCCACATCAGCGCGACATCAATCGACATTAAACCGAGTATCTTGTCAGCCTGGGGTGACGATGCGTCCCATTAAAGT";
    -    let my_kmer = "TTAA";
    +    let seq = "AAAGTGCTCTTAACTTGTCCCGCTCCACATCAGCGCGACATCAATCGACATTAAACCGAGTATCTTGTCAGCCTGGGGTGACGATGCGTCCCATTAAAGT";
    +    let my_kmer = "TTAA";
         let mut kmer = kmers_in_str(&seq, k, false);
         let obs = *kmer.entry(String::from(my_kmer)).or_insert(0);
    -    assert_eq!(obs, 3, "Found {} kmer in seq {} times. Seq is \n{}", my_kmer, obs, seq);
    +    assert_eq!(obs, 3, "Found {} kmer in seq {} times. Seq is \n{}", my_kmer, obs, seq);
     
         // But also test for revcom kmers
         let mut kmer = kmers_in_str(&seq, k, true );
         let obs = *kmer.entry(String::from(my_kmer)).or_insert(0);
    -    assert_eq!(obs, 6, "Found {} kmer in seq {} times. Seq is \n{}", my_kmer, obs, seq);
    +    assert_eq!(obs, 6, "Found {} kmer in seq {} times. Seq is \n{}", my_kmer, obs, seq);
     
         // one more kmer
    -    let my_kmer = "TGTC";
    +    let my_kmer = "TGTC";
         let mut kmer = kmers_in_str(&seq, k, false);
         let obs = *kmer.entry(String::from(my_kmer)).or_insert(0);
    -    assert_eq!(obs, 2, "Found {} kmer in seq {} times. Seq is \n{}", my_kmer, obs, seq);
    +    assert_eq!(obs, 2, "Found {} kmer in seq {} times. Seq is \n{}", my_kmer, obs, seq);
         // and revcom
         let mut kmer = kmers_in_str(&seq, k, true );
         let obs = *kmer.entry(String::from(my_kmer)).or_insert(0);
    -    assert_eq!(obs, 4, "Found {} kmer in seq {} times. Seq is \n{}", my_kmer, obs, seq);
    +    assert_eq!(obs, 4, "Found {} kmer in seq {} times. Seq is \n{}", my_kmer, obs, seq);
     }
     
     fn main(){
    @@ -424,22 +494,22 @@
     
         // script-specific options
         let default_k:usize = 21;
    -    opts.optopt("k","kmer-length",&format!("The size of the kmer (default: {})",default_k),"INT");
    -    opts.optflag("r","revcomp", "Count kmers on the reverse complement strand too");
    -    opts.optflag("m","remember-reads", "Add reads to subsequent columns. Each read begins with the kmer. Only lists reads in the forward direction.");
    +    opts.optopt("k","kmer-length",&format!("The size of the kmer (default: {})",default_k),"INT");
    +    opts.optflag("r","revcomp", "Count kmers on the reverse complement strand too");
    +    opts.optflag("m","remember-reads", "Add reads to subsequent columns. Each read begins with the kmer. Only lists reads in the forward direction.");
     
    -    let matches = fasten_base_options_matches("Counts kmers.", opts);
    +    let matches = fasten_base_options_matches("Counts kmers.", opts);
         
    -    //if matches.opt_present("paired-end") {
    -    //    logmsg("WARNING: --paired-end is not utilized in this script");
    +    //if matches.opt_present("paired-end") {
    +    //    logmsg("WARNING: --paired-end is not utilized in this script");
         //}
     
         let kmer_length:usize={
    -        if matches.opt_present("kmer-length") {
    -            matches.opt_str("kmer-length")
    -                .expect("ERROR: could not understand parameter --kmer-length")
    +        if matches.opt_present("kmer-length") {
    +            matches.opt_str("kmer-length")
    +                .expect("ERROR: could not understand parameter --kmer-length")
                     .parse()
    -                .expect("ERROR: --kmer-length is not an INT")
    +                .expect("ERROR: --kmer-length is not an INT")
             } else {
                 default_k
             }
    @@ -448,7 +518,7 @@
     
         let stdin = stdin();
         
    -    count_kmers(stdin, kmer_length, matches.opt_present("revcomp"), matches.opt_present("remember-reads"), matches.opt_present("paired-end"));
    +    count_kmers(stdin, kmer_length, matches.opt_present("revcomp"), matches.opt_present("remember-reads"), matches.opt_present("paired-end"));
     }
     
     /// Read fastq from stdin and count kmers
    @@ -456,14 +526,19 @@
     
         // keep track of which sequences start with which kmers
         let mut kmer_to_seqs :HashMap<String, Vec<String>> = HashMap::new();
    +
    +    // Some randomness
    +    let mut rng = rand::thread_rng();
    +    // Regular expression to find uncomplex kmers
    +    let low_complexity = Regex::new(r"N|(.)\1{2,}|(.)(.)(\2\3){1,}").unwrap();
         
         // read the file
         let my_buffer=BufReader::new(stdin);
         let mut buffer_iter = my_buffer.lines();
         let mut kmer_hash :HashMap<String,u32> = HashMap::new();
         while let Some(id_opt) = buffer_iter.next() {
    -        let seq = buffer_iter.next().expect("ERROR reading a sequence line")
    -            .expect("ERROR reading a sequence line");
    +        let seq = buffer_iter.next().expect("ERROR reading a sequence line")
    +            .expect("ERROR reading a sequence line");
             // burn the plus line
             let plus_opt = buffer_iter.next();
             // burn the qual line
    @@ -477,22 +552,23 @@
                     or_insert(0);
                 *kmer_count += value;
             }
    +        let kmer_keys: Vec<&String> = entry_kmers.keys().collect();
     
    -        // If this is paired end and if we're saving the second pair's
    +        // If this is paired end and if we're saving the second pair's
             // read, then reserve a declaired variable here for the string.
             let mut r2_read_string :String = String::new();
             if paired_end {
    -            let id2 = buffer_iter.next().expect("reading the ID2 line")
    -                .expect("reading the ID2 line");
    +            let id2 = buffer_iter.next().expect("reading the ID2 line")
    +                .expect("reading the ID2 line");
     
    -            let seq2 = buffer_iter.next().expect("ERROR reading a sequence line, second in pair")
    -                .expect("ERROR reading a sequence line, second in pair");
    +            let seq2 = buffer_iter.next().expect("ERROR reading a sequence line, second in pair")
    +                .expect("ERROR reading a sequence line, second in pair");
                 // burn the plus line
    -            let plus2 = buffer_iter.next().expect("reading the plus2 line")
    -                .expect("reading the plus2 line");
    +            let plus2 = buffer_iter.next().expect("reading the plus2 line")
    +                .expect("reading the plus2 line");
                 // burn the qual line
    -            let qual2 = buffer_iter.next().expect("reading the qual2 line")
    -                .expect("reading the qual2 line");
    +            let qual2 = buffer_iter.next().expect("reading the qual2 line")
    +                .expect("reading the qual2 line");
     
                 // get all the kmers in this entry
                 let entry_kmers2 = kmers_in_str(&seq2, kmer_length, revcomp);
    @@ -508,15 +584,32 @@
     
             // Remember the read that initiated this
             if remember_reads {
    -            let init_kmer = String::from(&seq[0..kmer_length]);
    -            let init_kmer_vec = kmer_to_seqs.entry(init_kmer).or_insert(vec![]);
    +            // Get the kmer substring
    +            // let init_kmer = String::from(&seq[0..kmer_length]);
    +            // Get the minimizer as the initial kmer
    +            //let init_kmer = calculate_minimizer(&seq, kmer_length);
    +
    +            //let init_kmer_pos = rand::thread_rng().gen_range(0 .. seq.len() - kmer_length + 1);
    +            //let init_kmer = seq[init_kmer_pos .. init_kmer_pos+kmer_length].to_string();
    +            let mut random_index = rng.gen_range(0..kmer_keys.len());
    +            let mut init_kmer    = kmer_keys[random_index].to_string();
    +            let mut kmer_tries :u16 = 0;
    +            while kmer_tries < 1000 && low_complexity.is_match(&init_kmer).unwrap() {
    +                random_index = rng.gen_range(0..kmer_keys.len());
    +                init_kmer    = kmer_keys[random_index].to_string();
    +                kmer_tries  += 1;
    +                //fasten::logmsg(format!("skipping kmer {}, try {}",&init_kmer, kmer_tries));
    +            }
    +
    +            // Get the vector of sequences for this kmer, or else initialize an empty vector
    +            let init_kmer_vec = kmer_to_seqs.entry(init_kmer).or_insert(vec![]);
     
                 // get the formatted entry
    -            let id   = id_opt.expect("reading the ID line");
    -            let plus = plus_opt.expect("reading the plus line")
    -                .expect("reading the plus line");
    -            let qual = qual_opt.expect("reading the qual line")
    -                .expect("reading the qual line");
    +            let id   = id_opt.expect("reading the ID line");
    +            let plus = plus_opt.expect("reading the plus line")
    +                .expect("reading the plus line");
    +            let qual = qual_opt.expect("reading the qual line")
    +                .expect("reading the qual line");
     
                 if paired_end {
                     init_kmer_vec.push(
    @@ -536,16 +629,16 @@
         // complement kmers before printing because it is basically
         // double the information needed.
         for (kmer,count) in kmer_hash.iter() {
    -        let mut line :String = format!("{}\t{}", kmer, count);
    +        let mut line :String = format!("{}\t{}", kmer, count);
             if remember_reads {
                 let reads_vec = kmer_to_seqs.entry(kmer.to_string()).or_insert(vec![]);
                 for read in reads_vec {
    -                line.push_str("\t");
    +                line.push_str("\t");
                     line.push_str(read);
                 }
             }
     
    -        println!("{}", line);
    +        println!("{}", line);
         }
     }
     
    @@ -556,9 +649,9 @@
         let mut kmer_hash :HashMap<String,u32> = HashMap::new();
         // how many kmers we expect in this sliding window
         let seq_len = seq.len();
    -    // Don't count short sequences
    +    // Don't count short sequences
         if seq_len < kmer_length {
    -        logmsg("WARNING: found a sequence less than k");
    +        logmsg("WARNING: found a sequence less than k");
             return kmer_hash;
         }
         let my_num_kmers = seq_len - kmer_length + 1;
    @@ -583,7 +676,40 @@
         return kmer_hash;
     }
     
    -/// reverse-complement a dna sequence
    +/*
    +fn calculate_minimizer(sequence: &str, k: usize) -> String {
    +    // Ensure the sequence length is greater than or equal to k
    +    if sequence.len() < k {
    +        panic!("Sequence length is less than k");
    +    }
    +
    +    // Initialize variables to keep track of the minimum k-mer and its hash
    +    let mut min_kmer = &sequence[0..k];
    +    let mut min_hash = hash_kmer(min_kmer);
    +
    +    // Iterate over the sequence to find the minimum k-mer and its hash
    +    for i in 1..=(sequence.len() - k) {
    +        let current_kmer = &sequence[i..(i + k)];
    +        let current_hash = hash_kmer(current_kmer);
    +
    +        // Update the minimum k-mer and its hash if a smaller hash is found
    +        if current_hash < min_hash {
    +            min_kmer = current_kmer;
    +            min_hash = current_hash;
    +        }
    +    }
    +
    +    // Return the minimizer k-mer
    +    min_kmer.to_string()
    +}
    +
    +fn hash_kmer(kmer: &str) -> u64 {
    +    // Simple hash function that converts each nucleotide to its ASCII value and sums them up
    +    kmer.bytes().map(|b| b as u64).sum()
    +}
    +*/
    +
    +/// reverse-complement a dna sequence
     // Thanks Henk for supplying these functions.
     fn revcomp(dna: &str) -> String {
         let mut rc_dna: String = String::with_capacity(dna.len());
    @@ -596,19 +722,19 @@
     /// Complementary nucleotide for ACTGUN, case insensitive
     fn switch_base(c: char) -> char {
         match c {
    -        'a' => 't',
    -        'c' => 'g',
    -        't' => 'a',
    -        'g' => 'c',
    -        'u' => 'a',
    -        'n' => 'n',
    -        'A' => 'T',
    -        'C' => 'G',
    -        'T' => 'A',
    -        'G' => 'C',
    -        'U' => 'A',
    -        'N' => 'N',
    -        _ => 'N',
    +        'a' => 't',
    +        'c' => 'g',
    +        't' => 'a',
    +        'g' => 'c',
    +        'u' => 'a',
    +        'n' => 'n',
    +        'A' => 'T',
    +        'C' => 'G',
    +        'T' => 'A',
    +        'G' => 'C',
    +        'U' => 'A',
    +        'N' => 'N',
    +        _ => 'N',
         }
     }
     
    diff --git a/docs/src/fasten_metrics/fasten_metrics.rs.html b/docs/src/fasten_metrics/fasten_metrics.rs.html
    index 1c7847a1..b20c551e 100644
    --- a/docs/src/fasten_metrics/fasten_metrics.rs.html
    +++ b/docs/src/fasten_metrics/fasten_metrics.rs.html
    @@ -1,4 +1,6 @@
    -fasten_metrics.rs - source
    1
    +fasten_metrics.rs - source
    +    
    1
     2
     3
     4
    @@ -205,7 +207,7 @@
     //!                        large output
     //!        --distribution STRING
     //!                        Print the distribution for each metric. Must supply
    -//!                        either 'normal' or 'nonparametric'
    +//!                        either 'normal' or 'nonparametric'
     //! ```
         
     extern crate fasten;
    @@ -223,47 +225,47 @@
     
     #[test]
     fn test_average_quality () {
    -    let easy_qual = "IIIIIIIIIIII";
    +    let easy_qual = "IIIIIIIIIIII";
         let easy_avg_obs = average_quality(easy_qual);
         let easy_avg_exp:f32 = 40.0;
    -    assert_eq!(easy_avg_obs, easy_avg_exp, "Tried to calculate average quality for {}", easy_qual);
    +    assert_eq!(easy_avg_obs, easy_avg_exp, "Tried to calculate average quality for {}", easy_qual);
     
         // a more difficult qual is the one in the first read in four_reads.fastq
    -    let hard_qual = "8AB*2D>C1'02C+=I@IEFHC7&-E5',I?E*33E/@3#68B%\"!B-/2%(G=*@D052IA!('7-*$+A6>.$89,-CG71=AGAE3&&#=2B.+I<E";
    +    let hard_qual = "8AB*2D>C1'02C+=I@IEFHC7&-E5',I?E*33E/@3#68B%\"!B-/2%(G=*@D052IA!('7-*$+A6>.$89,-CG71=AGAE3&&#=2B.+I<E";
         let hard_avg_obs = average_quality(hard_qual);
         let hard_avg_exp:f32 = 21.40;
    -    assert_eq!(hard_avg_obs, hard_avg_exp, "Tried to calculate the average quality for {}", hard_qual);
    +    assert_eq!(hard_avg_obs, hard_avg_exp, "Tried to calculate the average quality for {}", hard_qual);
     }
     
     fn main(){
         let mut opts = fasten_base_options();
     
         // script-specific options
    -    opts.optflag("","each-read","Print the metrics for each read. This creates very large output");
    -    opts.optopt("","distribution","Print the distribution for each metric. Must supply either 'normal' or 'nonparametric'","STRING");
    +    opts.optflag("","each-read","Print the metrics for each read. This creates very large output");
    +    opts.optopt("","distribution","Print the distribution for each metric. Must supply either 'normal' or 'nonparametric'","STRING");
     
    -    let matches = fasten_base_options_matches("Gives read metrics on a read set.", opts);
    +    let matches = fasten_base_options_matches("Gives read metrics on a read set.", opts);
     
    -    if matches.opt_present("paired-end") {
    -        logmsg("WARNING: --paired-end is not utilized in this script");
    +    if matches.opt_present("paired-end") {
    +        logmsg("WARNING: --paired-end is not utilized in this script");
         }
     
    -    let each_read :bool=matches.opt_present("each-read");
    +    let each_read :bool=matches.opt_present("each-read");
     
    -    let distribution = if matches.opt_present("distribution") {
    -        matches.opt_str("distribution")
    -            .expect("ERROR: could not understand parameter for --distribution")
    +    let distribution = if matches.opt_present("distribution") {
    +        matches.opt_str("distribution")
    +            .expect("ERROR: could not understand parameter for --distribution")
         } else {
             String::new()
         };
     
    -    let filename = "/dev/stdin";
    +    let filename = "/dev/stdin";
         
         // Header
         if each_read {
    -        println!("readID\treadLength\tavgQual");
    +        println!("readID\treadLength\tavgQual");
         } else {
    -        println!("{}",vec!["totalLength", "numReads", "avgReadLength","avgQual"].join("\t"));
    +        println!("{}",vec!["totalLength", "numReads", "avgReadLength","avgQual"].join("\t"));
     
         }
         
    @@ -272,7 +274,7 @@
         let mut num_lines   :u32   =0;
     
         // read the file
    -    let my_file = File::open(&filename).expect("Could not open file");
    +    let my_file = File::open(&filename).expect("Could not open file");
         let my_buffer=BufReader::new(my_file);
         for line in my_buffer.lines() {
             num_lines+=1;
    @@ -280,22 +282,22 @@
             match num_lines % 4 {
                 1 => {
                     if each_read {
    -                    let id = line.expect("Expected an ID line");
    -                    print!("{}\t",&id[1..]);
    +                    let id = line.expect("Expected an ID line");
    +                    print!("{}\t",&id[1..]);
                     }
                 }
                 2 => {
    -                let my_read_length=line.expect("Expected a sequence line").len() as f32;
    +                let my_read_length=line.expect("Expected a sequence line").len() as f32;
                     if each_read {
    -                    print!("{}\t",my_read_length);
    +                    print!("{}\t",my_read_length);
                     }
                     read_length.push(my_read_length);
                 }
                 0 => {
    -                let qual_line=line.expect("Expected a qual line");
    +                let qual_line=line.expect("Expected a qual line");
                     let my_avg_qual:f32 = average_quality(&qual_line);
                     if each_read {
    -                    println!("{}",my_avg_qual);
    +                    println!("{}",my_avg_qual);
                     }
                     read_qual.push(my_avg_qual);
                 }
    @@ -312,29 +314,29 @@
         // add statistics if requested
         let mut total_length_str = (total_length as f32/num_reads as f32).to_string();
         let mut total_qual_str   = ((read_qual.iter().fold(0.0,|a,&b| a+b)) / num_reads as f32).to_string();
    -    if distribution == "normal" {
    -        total_length_str.push_str("±");
    +    if distribution == "normal" {
    +        total_length_str.push_str("±");
             total_length_str.push_str(&standard_deviation(&read_length).to_string());
    -        total_qual_str.push_str("±");
    +        total_qual_str.push_str("±");
             total_qual_str.push_str(&standard_deviation(&read_qual).to_string());
     
             summary_metrics.push(total_length_str);
             summary_metrics.push(total_qual_str);
         }
         // TODO median absolute deviation or similar
    -    else if distribution == "nonparametric" {
    -        eprintln!("WARNING: nonparametric distribution not yet supported");
    +    else if distribution == "nonparametric" {
    +        eprintln!("WARNING: nonparametric distribution not yet supported");
     
    -    } else if distribution == "" {
    +    } else if distribution == "" {
             summary_metrics.push(total_length_str);
             summary_metrics.push(total_qual_str);
         } else {
    -        panic!("I did not understand --distribution {}",distribution);
    +        panic!("I did not understand --distribution {}",distribution);
         }
     
         // summary metrics
         if !each_read {
    -        println!("{}", summary_metrics.join("\t"));
    +        println!("{}", summary_metrics.join("\t"));
         }
     
     }
    diff --git a/docs/src/fasten_mutate/fasten_mutate.rs.html b/docs/src/fasten_mutate/fasten_mutate.rs.html
    index e1ea5ec8..ed0b5bfc 100644
    --- a/docs/src/fasten_mutate/fasten_mutate.rs.html
    +++ b/docs/src/fasten_mutate/fasten_mutate.rs.html
    @@ -1,4 +1,6 @@
    -fasten_mutate.rs - source
    1
    +fasten_mutate.rs - source
    +    
    1
     2
     3
     4
    @@ -175,57 +177,57 @@
     fn main(){
         let mut opts = fasten_base_options();
         // Options specific to this script
    -    opts.optopt("s", "snps", "Maximum number of SNPs (point mutations) to include per read.", "INT");
    -    opts.optflag("m", "mark", "lowercase all reads but uppercase the SNPs (not yet implemented)");
    +    opts.optopt("s", "snps", "Maximum number of SNPs (point mutations) to include per read.", "INT");
    +    opts.optflag("m", "mark", "lowercase all reads but uppercase the SNPs (not yet implemented)");
     
    -    let description = "Introduces point mutations randomly. There is no evolutionary model; multiple hits are allowed. Therefore, the number of SNPs through --snps is an upper limit."
    +    let description = "Introduces point mutations randomly. There is no evolutionary model; multiple hits are allowed. Therefore, the number of SNPs through --snps is an upper limit."
                           .to_string();
    -    let regex = Regex::new(r"(.{1,60}\s+)").unwrap();
    -    let wrapped_description = regex.replace_all(&description, "$1\n");
    +    let regex = Regex::new(r"(.{1,60}\s+)").unwrap();
    +    let wrapped_description = regex.replace_all(&description, "$1\n");
     
         let matches = fasten_base_options_matches(&wrapped_description, opts);
     
    -    if matches.opt_present("paired-end") {
    -        logmsg("WARNING: --paired-end is not utilized in this script");
    +    if matches.opt_present("paired-end") {
    +        logmsg("WARNING: --paired-end is not utilized in this script");
         }
     
         // Figure out the number of SNPs per read
    -    let num_snps:u8 = if matches.opt_present("snps") { 
    -        matches.opt_str("snps").unwrap()
    -            .parse().expect("--snps needs to be a FLOAT")
    +    let num_snps:u8 = if matches.opt_present("snps") { 
    +        matches.opt_str("snps").unwrap()
    +            .parse().expect("--snps needs to be a FLOAT")
         } else {
    -        panic!("ERROR: --snps is required")
    +        panic!("ERROR: --snps is required")
         };
     
         // Not sure if I should expose NTs to a flag if someone
         // wants more nucleotide codes like N.
    -    let mark:bool = if matches.opt_present("mark"){
    +    let mark:bool = if matches.opt_present("mark"){
             true
         } else {
             false
         };
     
     
    -    let nts = vec!['A', 'C', 'G', 'T'];
    -    //let nts = vec!['a', 'c', 'g', 't'];
    +    let nts = vec!['A', 'C', 'G', 'T'];
    +    //let nts = vec!['a', 'c', 'g', 't'];
     
         // Make this one time outside the loop to keep overhead low
     
    -    let my_file = File::open("/dev/stdin").expect("Could not open file");
    +    let my_file = File::open("/dev/stdin").expect("Could not open file");
         let my_buffer=BufReader::new(my_file);
         let mut buffer_iter = my_buffer.lines();
         while let Some(line) = buffer_iter.next() {
    -        let id  = line.expect("ERROR reading the ID line");
    -        let seq = buffer_iter.next().expect("ERROR reading a sequence line")
    -            .expect("ERROR reading a sequence line");
    -        buffer_iter.next().expect("ERROR reading a plus line")
    -            .expect("ERROR reading the plus line");
    -        let qual= buffer_iter.next().expect("ERROR reading a qual line")
    -            .expect("ERROR reading a qual line");
    +        let id  = line.expect("ERROR reading the ID line");
    +        let seq = buffer_iter.next().expect("ERROR reading a sequence line")
    +            .expect("ERROR reading a sequence line");
    +        buffer_iter.next().expect("ERROR reading a plus line")
    +            .expect("ERROR reading the plus line");
    +        let qual= buffer_iter.next().expect("ERROR reading a qual line")
    +            .expect("ERROR reading a qual line");
     
             let new_seq = mutate(&seq, &nts, num_snps, mark);
     
    -        println!("{}\n{}\n+\n{}",id,new_seq,qual);
    +        println!("{}\n{}\n+\n{}",id,new_seq,qual);
     
         }
     }
    diff --git a/docs/src/fasten_normalize/fasten_normalize.rs.html b/docs/src/fasten_normalize/fasten_normalize.rs.html
    index f821cfe9..2d0cd496 100644
    --- a/docs/src/fasten_normalize/fasten_normalize.rs.html
    +++ b/docs/src/fasten_normalize/fasten_normalize.rs.html
    @@ -1,4 +1,6 @@
    -fasten_normalize.rs - source
    1
    +fasten_normalize.rs - source
    +    
    1
     2
     3
     4
    @@ -150,6 +152,17 @@
     150
     151
     152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
     
    //! Normalizes kmer depth by removing some reads from high kmer depths
     //! The input has to be from `fasten_kmer --remember-reads` where there are at least three columns:
     //! kmer, count, read1, [read2,...]
    @@ -231,23 +244,23 @@
     
     /// Glues together paired end reads internally and is a
     /// character not expected in any read
    -const READ_SEPARATOR :char = '~';
    +const READ_SEPARATOR :char = '~';
     
     fn main(){
         let mut opts = fasten_base_options();
     
         // script-specific options
    -    opts.optopt("t", "target-depth", "The target depth of kmer.", "INT");
    -    let matches = fasten_base_options_matches("Normalizes reads based on kmer coverage.", opts);
    +    opts.optopt("t", "target-depth", "The target depth of kmer.", "INT");
    +    let matches = fasten_base_options_matches("Normalizes reads based on kmer coverage.", opts);
     
    -    let target_depth :u32 = matches.opt_str("target-depth")
    -        .expect("need --target-depth")
    +    let target_depth :u32 = matches.opt_str("target-depth")
    +        .expect("need --target-depth")
             .parse()
    -        .expect("Convert target-depth to integer");
    +        .expect("Convert target-depth to integer");
     
         let stdin = stdin();
     
    -    let paired_end = matches.opt_present("paired-end");
    +    let paired_end = matches.opt_present("paired-end");
         
         normalize_coverage(stdin, target_depth, paired_end);
     }
    @@ -260,45 +273,56 @@
         // read the file
         let my_buffer=BufReader::new(stdin);
         let mut buffer_iter = my_buffer.lines();
    -    while let Some(line_opt) = buffer_iter.next() {
    -        let line = line_opt.expect("read the next line");
     
    -        // get the fields: kmer, count, reads...
    -        let mut f :Vec<&str> = line.split("\t").collect();
    +    // Iterate over each line in the buffer
    +    while let Some(line_opt) = buffer_iter.next() {
    +        let line = line_opt.expect("read the next line");
    +
    +        // Split the line into fields separated by tabs
    +        // get the fields: kmer, count, read1[, read2...]
    +        let mut f :Vec<&str> = line.split("\t").collect();
             // No need to normalize if there are no reads and therefore nothing in field 3
             if f.len() < 3 {
                 continue;
             }
     
    -        let kmer_count :Vec<&str> = f.splice(0..2, vec![]).collect();
    -        //let _kmer = kmer_count[0];
    -        let count :u32 = kmer_count[1].parse().unwrap();
    +        // Extract kmer and count fields
    +        // and remove them from the fields vector f.
    +        let kmer_count :Vec<&str> = f.splice(0..2, vec![]).collect();
    +        let _count :u32 = kmer_count[1].parse().unwrap();
    +        let num_reads_orig :usize = f.len();
     
             // number of reads to keep is the target depth / kmer coverage * number of reads present
             let mut num_reads_to_keep :usize = min(
    -            (target_depth as f32 / count as f32 * f.len() as f32).ceil() as usize,
    -            f.len() as usize
    +            target_depth,
    +            num_reads_orig as u32
             ) as usize;
    -        if paired_end {
    +        //fasten::logmsg(format!("{} = {} <=> {}", num_reads_to_keep, &target_depth, &num_reads_orig));
    +
    +        // If paired end, cut this number in two
    +        if paired_end {
                 num_reads_to_keep = (num_reads_to_keep as f32 / 2.0).ceil() as usize;
             }
     
    -        //println!("target depth:{} count:{} num reads:{} = {}", target_depth, count, f.len(), num_reads_to_keep);
    +        //println!("target depth:{} count:{} num reads:{} = {}", target_depth, count, f.len(), num_reads_to_keep);
             
             // shuffle the reads in place
             f.shuffle(&mut rng);
    +
             // take the top X reads
             let reads_to_keep :Vec<&str> = f.splice(0..num_reads_to_keep, vec![]).collect();
     
    -        print_reads(reads_to_keep);
    +        //fasten::logmsg(format!("Reads to keep: {} vs {}", &num_reads_to_keep, &count));
    +
    +        print_reads(reads_to_keep);
         }
     }
     
    -/// Print the reads in fastq format when given in a single line with `~`
    +/// Print the reads in fastq format when given in a single line with `READ_SEPARATOR`
     fn print_reads (reads:Vec<&str>) {
         for entry in reads{
    -        let entry_string = entry.replace(READ_SEPARATOR, "\n");
    -        println!("{}", entry_string);
    +        let entry_string = entry.replace(READ_SEPARATOR, "\n");
    +        println!("{}", entry_string);
         }
     }
     
    diff --git a/docs/src/fasten_pe/fasten_pe.rs.html b/docs/src/fasten_pe/fasten_pe.rs.html
    index cb742359..f5f7f25a 100644
    --- a/docs/src/fasten_pe/fasten_pe.rs.html
    +++ b/docs/src/fasten_pe/fasten_pe.rs.html
    @@ -1,4 +1,6 @@
    -fasten_pe.rs - source
    1
    +fasten_pe.rs - source
    +    
    1
     2
     3
     4
    @@ -195,11 +197,11 @@
     //! 
     //! ## Test the file and then print a message with the exit code
     //! ```bash
    -//! cat file.fastq | fasten_pe; echo "Reads were paired-end? $?";
    +//! cat file.fastq | fasten_pe; echo "Reads were paired-end? $?";
     //! ```
     //! ## Test the file and if it is paired end (exit code 0), then print a message
     //! ```bash
    -//! cat file.fastq | fasten_pe || echo "Reads were paired end.";
    +//! cat file.fastq | fasten_pe || echo "Reads were paired end.";
     //! ```
     //! 
     //! # Usage
    @@ -228,14 +230,14 @@
     
     fn main() {
         let mut opts = fasten_base_options();
    -    opts.optflag("","print-reads","Print each read. Useful for Unix pipes.");
    -    let matches = fasten_base_options_matches("Determine paired-end-ness in an interleaved file. Exit code of 0 indicates PE. Exit code > 0 indicates SE.", opts);
    +    opts.optflag("","print-reads","Print each read. Useful for Unix pipes.");
    +    let matches = fasten_base_options_matches("Determine paired-end-ness in an interleaved file. Exit code of 0 indicates PE. Exit code > 0 indicates SE.", opts);
         
    -    if matches.opt_present("paired-end") {
    -        logmsg("WARNING: --paired-end was supplied but this script is supposed to determine whether the input is paired-end.");
    +    if matches.opt_present("paired-end") {
    +        logmsg("WARNING: --paired-end was supplied but this script is supposed to determine whether the input is paired-end.");
         }
     
    -    let should_print = matches.opt_present("print-reads");
    +    let should_print = matches.opt_present("print-reads");
     
         // Save the top X ID pairs in a vector
         // and compare them in several functions that test for
    @@ -243,37 +245,37 @@
         // it is paired-end input.
         let mut id1_vec :Vec<String>=Vec::new();
         let mut id2_vec :Vec<String>=Vec::new();
    -    let my_file = File::open("/dev/stdin").expect("Could not open file");
    +    let my_file = File::open("/dev/stdin").expect("Could not open file");
         let my_buffer=BufReader::new(my_file);
         let mut lines = my_buffer.lines();
         while let Some(line) = lines.next() {
    -        let id1 = line.expect("ERROR parsing id line in R1");
    +        let id1 = line.expect("ERROR parsing id line in R1");
             let mut entry=id1.clone();
    -        entry.push('\n');
    +        entry.push('\n');
             for _ in 1..4 { // move ahead three lines
                 let other_line = lines.next()
    -                .expect("ERROR getting next line")
    -                .expect("ERROR parsing next line");
    +                .expect("ERROR getting next line")
    +                .expect("ERROR parsing next line");
                 entry.push_str(&other_line);
    -            entry.push('\n');
    +            entry.push('\n');
             }
             let id2 = lines.next()
    -            .expect("ERROR getting R2. This is not a paired end file.")
    -            .expect("ERROR parsing next line in R2");
    +            .expect("ERROR getting R2. This is not a paired end file.")
    +            .expect("ERROR parsing next line in R2");
             entry.push_str(&id2);
    -        entry.push('\n');
    +        entry.push('\n');
             for _ in 1..4 { // move ahead three lines
                 let other_line = lines.next()
    -                .expect("ERROR getting next line in R2. This is not a paired end file.")
    -                .expect("ERROR parsing next line in R2");
    +                .expect("ERROR getting next line in R2. This is not a paired end file.")
    +                .expect("ERROR parsing next line in R2");
                 entry.push_str(&other_line);
    -            entry.push('\n');
    +            entry.push('\n');
             }
             id1_vec.push(id1);
             id2_vec.push(id2);
     
             if should_print {
    -            print!("{}",entry);
    +            print!("{}",entry);
             }
         }
     
    @@ -286,14 +288,14 @@
     
         // If this is not paired end, return a nonzero
         if is_paired_end == 0 {
    -        if matches.opt_present("verbose") {
    -            logmsg("I do not think this is interleaved paired end");
    +        if matches.opt_present("verbose") {
    +            logmsg("I do not think this is interleaved paired end");
             }
             std::process::exit(1);
         }
         
    -    if matches.opt_present("verbose") {
    -        logmsg("The fastq input seems to be interleaved paired-end");
    +    if matches.opt_present("verbose") {
    +        logmsg("The fastq input seems to be interleaved paired-end");
         }
     
     }
    @@ -307,12 +309,12 @@
         let id2_vec = id2_ref.clone();
         
         // @.../1
    -    let slash_r1r2_regex = Regex::new(r"(.+)/([12])$").expect("malformed qual regex");
    +    let slash_r1r2_regex = Regex::new(r"(.+)/([12])$").expect("malformed qual regex");
     
         let mut id2_iter = id2_vec.iter();
         for id1 in id1_vec.iter(){
             let id2 = id2_iter.next()
    -            .expect("ERROR getting next id2");
    +            .expect("ERROR getting next id2");
     
             let caps1_result = slash_r1r2_regex.captures(&id1);
             let caps2_result = slash_r1r2_regex.captures(&id2);
    @@ -324,16 +326,16 @@
     
             // If we have a match then get the captured values
             let caps1 = caps1_result
    -            .expect("ERROR: could not regex against id1");
    +            .expect("ERROR: could not regex against id1");
             let caps2 = caps2_result
    -            .expect("ERROR: could not regex against id2");
    +            .expect("ERROR: could not regex against id2");
     
             // Make sure the base name matches
             if caps1[1] != caps2[1] {
                 return 0;
             }
             // Make sure there is a 1/2 combo
    -        if &caps1[2] != "1" || &caps2[2] != "2" {
    +        if &caps1[2] != "1" || &caps2[2] != "2" {
                 return 0;
             }
         }
    @@ -352,25 +354,25 @@
     
         for id1 in id1_vec.iter(){
             let id2 = id2_iter.next()
    -            .expect("ERROR getting next id2");
    +            .expect("ERROR getting next id2");
     
     
             // Get the 7th field which is a combination of the
             // Y position and the read number, separated by a
             // space.
    -        let id1_tmp = id1.split(":").nth(6);
    -        let id2_tmp = id2.split(":").nth(6);
    +        let id1_tmp = id1.split(":").nth(6);
    +        let id2_tmp = id2.split(":").nth(6);
             if id1_tmp.is_none() || id2_tmp.is_none() {
                 return 0;
             }
     
             // Get the read number. It has to be 1 and 2.
    -        let id1_read_number = id1_tmp.unwrap().split(" ").nth(1);
    -        let id2_read_number = id2_tmp.unwrap().split(" ").nth(1);
    +        let id1_read_number = id1_tmp.unwrap().split(" ").nth(1);
    +        let id2_read_number = id2_tmp.unwrap().split(" ").nth(1);
             if id1_read_number.is_none() || id2_read_number.is_none() {
                 return 0;
             }
    -        if id1_read_number.unwrap() != "1" || id2_read_number.unwrap() != "2" {
    +        if id1_read_number.unwrap() != "1" || id2_read_number.unwrap() != "2" {
                 return 0;
             }
         }
    diff --git a/docs/src/fasten_progress/fasten_progress.rs.html b/docs/src/fasten_progress/fasten_progress.rs.html
    index 0ca33488..bed52818 100644
    --- a/docs/src/fasten_progress/fasten_progress.rs.html
    +++ b/docs/src/fasten_progress/fasten_progress.rs.html
    @@ -1,4 +1,6 @@
    -fasten_progress.rs - source
    1
    +fasten_progress.rs - source
    +    
    1
     2
     3
     4
    @@ -174,34 +176,34 @@
     fn main(){
         let mut opts = fasten_base_options();
         // Options specific to this script
    -    opts.optopt("","id","Progress identifier. Default: unnamed","STRING");
    -    opts.optopt("","update-every","Update progress every n reads.","INT");
    -    opts.optflag("p","print","Print the reads back to stdout");
    +    opts.optopt("","id","Progress identifier. Default: unnamed","STRING");
    +    opts.optopt("","update-every","Update progress every n reads.","INT");
    +    opts.optflag("p","print","Print the reads back to stdout");
     
    -    let matches = fasten_base_options_matches("Prints a progress meter for number of fastq entries", opts);
    +    let matches = fasten_base_options_matches("Prints a progress meter for number of fastq entries", opts);
     
    -    let print_reads:bool = matches.opt_present("print");
    +    let print_reads:bool = matches.opt_present("print");
     
         let progress_id:String = {
    -      if matches.opt_present("id") {
    -        matches.opt_str("id")
    -          .expect("ERROR parsing --id")
    +      if matches.opt_present("id") {
    +        matches.opt_str("id")
    +          .expect("ERROR parsing --id")
           } else {
    -        String::from("unnamed")
    +        String::from("unnamed")
           }
         };
     
    -    let my_file = File::open("/dev/stdin").expect("Could not open file");
    +    let my_file = File::open("/dev/stdin").expect("Could not open file");
         let my_buffer=BufReader::new(my_file);
     
         let lines_per_read :usize = 4;
         let update_every :usize  = {
    -        if matches.opt_present("update-every") {
    +        if matches.opt_present("update-every") {
                 let tmp :usize = 
    -                matches.opt_str("update-every")
    -                 .expect("ERROR parsing update-every")
    +                matches.opt_str("update-every")
    +                 .expect("ERROR parsing update-every")
                      .parse()
    -                 .expect("ERROR parsing update-every as INT");
    +                 .expect("ERROR parsing update-every as INT");
                 tmp * lines_per_read
                 //tmp
             } else {
    @@ -210,28 +212,28 @@
         };
     
         let mut line_counter = 0;
    -    eprint!("\r{} progress: {}", progress_id, line_counter/lines_per_read);
    +    eprint!("\r{} progress: {}", progress_id, line_counter/lines_per_read);
         for res in my_buffer.lines() {
    -        let line=res.expect("ERROR: did not get a line");
    +        let line=res.expect("ERROR: did not get a line");
             if print_reads {
    -            println!("{}", line);
    +            println!("{}", line);
             }
             line_counter += 1;
     
             match line_counter % update_every {
                 0=>{
    -                //println!("UPDATE: {}", line_counter);
    -                eprint!("\r{} progress: {}", progress_id, line_counter/lines_per_read);
    -                //eprint!(".");
    +                //println!("UPDATE: {}", line_counter);
    +                eprint!("\r{} progress: {}", progress_id, line_counter/lines_per_read);
    +                //eprint!(".");
                 }
                 _=>{
     
                 }
             }
         }
    -    eprint!("\n");
    +    eprint!("\n");
     
    -    let msg = format!("{}: Finished progress on {} reads", progress_id, line_counter);
    +    let msg = format!("{}: Finished progress on {} reads", progress_id, line_counter);
         fasten::logmsg(&msg);
     }
     
    diff --git a/docs/src/fasten_quality_filter/fasten_quality_filter.rs.html b/docs/src/fasten_quality_filter/fasten_quality_filter.rs.html
    index 9cfac3f7..75252855 100644
    --- a/docs/src/fasten_quality_filter/fasten_quality_filter.rs.html
    +++ b/docs/src/fasten_quality_filter/fasten_quality_filter.rs.html
    @@ -1,4 +1,6 @@
    -fasten_quality_filter.rs - source
    1
    +fasten_quality_filter.rs - source
    +    
    1
     2
     3
     4
    @@ -100,7 +102,7 @@
     100
     101
     102
    -
    //! Transforms any low-quality base to 'N'
    +
    //! Transforms any low-quality base to 'N'
     //! 
     //! # Examples
     //! 
    @@ -120,7 +122,7 @@
     //!     -v, --verbose       Print more status messages
     //!     -m, --max-quality INT
     //!                         The maximum quality at which a base will be
    -//!                         transformed to 'N'
    +//!                         transformed to 'N'
     //! ```    
     extern crate fasten;
     extern crate statistical;
    @@ -138,20 +140,20 @@
         let mut opts = fasten_base_options();
     
         // script-specific options
    -    opts.optopt("m","max-quality","The maximum quality at which a base will be transformed to 'N'","INT");
    +    opts.optopt("m","max-quality","The maximum quality at which a base will be transformed to 'N'","INT");
     
    -    let matches = fasten_base_options_matches("Transforms any low-quality base to 'N'.", opts);
    +    let matches = fasten_base_options_matches("Transforms any low-quality base to 'N'.", opts);
         
    -    if matches.opt_present("paired-end") {
    -        logmsg("WARNING: --paired-end is not utilized in this script");
    +    if matches.opt_present("paired-end") {
    +        logmsg("WARNING: --paired-end is not utilized in this script");
         }
     
         let max_quality_offset :u8={
    -        if matches.opt_present("max-quality") {
    -            matches.opt_str("max-quality")
    -                .expect("ERROR: could not understand parameter --max-quality")
    +        if matches.opt_present("max-quality") {
    +            matches.opt_str("max-quality")
    +                .expect("ERROR: could not understand parameter --max-quality")
                     .parse()
    -                .expect("ERROR: --max-quality is not an INT")
    +                .expect("ERROR: --max-quality is not an INT")
             } else {
                0 
             }
    @@ -159,10 +161,10 @@
         let max_quality :u8 = max_quality_offset + 33;
     
     
    -    let filename = "/dev/stdin";
    +    let filename = "/dev/stdin";
         
         // read the file
    -    let my_file = File::open(&filename).expect("Could not open file");
    +    let my_file = File::open(&filename).expect("Could not open file");
         let my_buffer=BufReader::new(my_file);
         let mut num_lines=0;
     
    @@ -173,29 +175,29 @@
     
             match num_lines % 4 {
                 1 => {
    -                current_id = line.expect("ERROR reading id line");
    +                current_id = line.expect("ERROR reading id line");
                 }
                 2 => {
    -                current_seq = line.expect("ERROR reading seq line");
    +                current_seq = line.expect("ERROR reading seq line");
                 }
                 0 => {
    -                let current_qual_cigar = line.expect("ERROR reading qual line");
    +                let current_qual_cigar = line.expect("ERROR reading qual line");
                     let mut seq_chars = current_seq.chars();
                     let mut new_seq =String::new();
                     let mut new_qual=String::new();
                     for current_qual in current_qual_cigar.chars() {
    -                    let current_nt=seq_chars.next().expect("ERROR: could not get the next nt in the sequence");
    +                    let current_nt=seq_chars.next().expect("ERROR: could not get the next nt in the sequence");
                         let phred = current_qual as u8;
                         if phred < max_quality {
    -                        new_seq.push('N');
    -                        new_qual.push('!');
    +                        new_seq.push('N');
    +                        new_qual.push('!');
                         } else {
                             new_seq.push(current_nt);
                             new_qual.push(current_qual);
                         }
                     }
     
    -                println!("{}\n{}\n+\n{}",&current_id,new_seq,new_qual);
    +                println!("{}\n{}\n+\n{}",&current_id,new_seq,new_qual);
                 }
                 _ => { }
             };
    diff --git a/docs/src/fasten_randomize/fasten_randomize.rs.html b/docs/src/fasten_randomize/fasten_randomize.rs.html
    index 8b6e0e83..8c905ffe 100644
    --- a/docs/src/fasten_randomize/fasten_randomize.rs.html
    +++ b/docs/src/fasten_randomize/fasten_randomize.rs.html
    @@ -1,4 +1,6 @@
    -fasten_randomize.rs - source
    1
    +fasten_randomize.rs - source
    +    
    1
     2
     3
     4
    @@ -97,7 +99,7 @@
     //! # Examples
     //! 
     //! ```perl
    -//! print "hello world\n";
    +//! print "hello world\n";
     //! ```
     //!
     //! ## General usage
    @@ -142,10 +144,10 @@
     fn main(){
         let opts = fasten_base_options();
     
    -    let matches = fasten_base_options_matches("Create random reads from stdin.", opts);
    +    let matches = fasten_base_options_matches("Create random reads from stdin.", opts);
     
         let lines_per_read :u32={
    -        if matches.opt_present("paired-end") {
    +        if matches.opt_present("paired-end") {
                 8
             }else{
                 4
    @@ -160,16 +162,16 @@
     fn print_reads_from_stdin(lines_per_read :u32) -> () {
         // Start off with a capacity of 100k reads.
         let mut seqs :Vec<String> = Vec::with_capacity(100000);
    -    let my_file = File::open("/dev/stdin").expect("Could not open stdin");
    +    let my_file = File::open("/dev/stdin").expect("Could not open stdin");
         let my_buffer=BufReader::new(my_file);
         let mut lines = my_buffer.lines();
         while let Some(id) = lines.next() {
    -        let mut entry = id.expect("ERROR: could not parse the ID line");
    +        let mut entry = id.expect("ERROR: could not parse the ID line");
             for _ in 1..lines_per_read {
    -            entry.push('\n');
    +            entry.push('\n');
                 let next_line = lines.next()
    -                .expect("ERROR: could not get the next line")
    -                .expect("ERROR: could not parse the next line");
    +                .expect("ERROR: could not get the next line")
    +                .expect("ERROR: could not parse the next line");
                 entry.push_str(&next_line);
             }
     
    @@ -181,7 +183,7 @@
         //rng.shuffle(&mut seqs);
         seqs.shuffle(&mut rng);
         for seq in seqs {
    -        println!("{}",seq);
    +        println!("{}",seq);
         }
     }
     
    diff --git a/docs/src/fasten_regex/fasten_regex.rs.html b/docs/src/fasten_regex/fasten_regex.rs.html
    index a95c7b49..6e89f254 100644
    --- a/docs/src/fasten_regex/fasten_regex.rs.html
    +++ b/docs/src/fasten_regex/fasten_regex.rs.html
    @@ -1,4 +1,6 @@
    -fasten_regex.rs - source
    1
    +fasten_regex.rs - source
    +    
    1
     2
     3
     4
    @@ -190,12 +192,12 @@
     //! 
     //! ## Find a specific read
     //! ```bash
    -//! cat file.fastq | fasten_regex --which ID --regex 'my-specific-read-id-1234' > my_read.fastq
    +//! cat file.fastq | fasten_regex --which ID --regex 'my-specific-read-id-1234' > my_read.fastq
     //! ```
     //!
     //! ## Find a specific read but also keep its pair
     //! ```bash
    -//! cat file.fastq | fasten_regex --which ID --regex 'my-specific-read-id-1234' --paired-end > my_pairs.fastq
    +//! cat file.fastq | fasten_regex --which ID --regex 'my-specific-read-id-1234' --paired-end > my_pairs.fastq
     //! ```
     //!
     //! ## Find a specific motif
    @@ -213,7 +215,7 @@
     //!     -n, --numcpus INT   Number of CPUs (default: 1)
     //!     -p, --paired-end    The input reads are interleaved paired-end
     //!     -v, --verbose       Print more status messages
    -//!     -r, --regex STRING  Regular expression (default: '.')
    +//!     -r, --regex STRING  Regular expression (default: '.')
     //!     -w, --which String  Which field to match on? ID, SEQ, QUAL. Default: SEQ
     //! ```
     extern crate getopts;
    @@ -234,54 +236,54 @@
     fn main(){
         let mut opts = fasten_base_options();
         // Options specific to this script
    -    opts.optopt("r","regex","Regular expression (default: '.')","STRING");
    -    opts.optopt("w","which","Which field to match on? ID, SEQ, QUAL. Default: SEQ","String");
    -    //opts.optflag("e","exclude","Exclude these reads instead of including them");
    +    opts.optopt("r","regex","Regular expression (default: '.')","STRING");
    +    opts.optopt("w","which","Which field to match on? ID, SEQ, QUAL. Default: SEQ","String");
    +    //opts.optflag("e","exclude","Exclude these reads instead of including them");
     
    -    let matches = fasten_base_options_matches("Filter reads based on a regular expression.", opts);
    +    let matches = fasten_base_options_matches("Filter reads based on a regular expression.", opts);
     
         let (tx, rx):(std::sync::mpsc::Sender<String>,std::sync::mpsc::Receiver<String>) = channel();
     
    -    let my_file = File::open("/dev/stdin").expect("Could not open file");
    +    let my_file = File::open("/dev/stdin").expect("Could not open file");
         let my_buffer=BufReader::new(my_file);
     
    -    let is_paired_end=matches.opt_present("paired-end");
    +    let is_paired_end=matches.opt_present("paired-end");
     
         let which_field:String={
    -        if matches.opt_present("which") {
    -            matches.opt_str("which").expect("ERROR parsing --which")
    +        if matches.opt_present("which") {
    +            matches.opt_str("which").expect("ERROR parsing --which")
                     .to_uppercase()
             } else {
    -            "SEQ".to_string()
    +            "SEQ".to_string()
             }
         };
     
         let num_cpus:usize = {
    -        if matches.opt_present("numcpus") {
    -            matches.opt_str("numcpus").expect("ERROR parsing --numcpus")
    +        if matches.opt_present("numcpus") {
    +            matches.opt_str("numcpus").expect("ERROR parsing --numcpus")
                     .parse()
    -                .expect("ERROR: numcpus is not an integer")
    +                .expect("ERROR: numcpus is not an integer")
             } else {
                 1
             }
         };
     
    -    // by default the regex parameter will be "." for "everything"
    +    // by default the regex parameter will be "." for "everything"
         let regex_param={
    -        if matches.opt_present("regex") {
    -            matches.opt_str("regex")
    -                .expect("ERROR: could not parse regex parameter")
    +        if matches.opt_present("regex") {
    +            matches.opt_str("regex")
    +                .expect("ERROR: could not parse regex parameter")
             } else {
    -            String::from(".")
    +            String::from(".")
             }
         };
     
         // Error checking the regex in the main thread
         let _regex = Regex::new(&regex_param)
    -        .expect("malformed seq regex given by --regex");
    +        .expect("malformed seq regex given by --regex");
     
    -    if matches.opt_present("verbose") {
    -        eprintln!("Regular expression: {}",regex_param);
    +    if matches.opt_present("verbose") {
    +        eprintln!("Regular expression: {}",regex_param);
         }
     
         let pool = ThreadPool::new(num_cpus);
    @@ -289,13 +291,13 @@
         let mut buffer_iter = my_buffer.lines();
     
         while let Some(line) = buffer_iter.next() {
    -        let id  = line.expect("ERROR reading the ID line");
    -        let seq = buffer_iter.next().expect("ERROR reading a sequence line")
    -            .expect("ERROR reading a sequence line");
    -                  buffer_iter.next().expect("ERROR reading a plus line")
    -                      .expect("ERROR reading the plus line");
    -        let qual= buffer_iter.next().expect("ERROR reading a qual line")
    -            .expect("ERROR reading a qual line");
    +        let id  = line.expect("ERROR reading the ID line");
    +        let seq = buffer_iter.next().expect("ERROR reading a sequence line")
    +            .expect("ERROR reading a sequence line");
    +                  buffer_iter.next().expect("ERROR reading a plus line")
    +                      .expect("ERROR reading the plus line");
    +        let qual= buffer_iter.next().expect("ERROR reading a qual line")
    +            .expect("ERROR reading a qual line");
     
             // Things to regex-match on
             let mut all_id    =id.clone();
    @@ -308,14 +310,14 @@
     
             // Get R2
             if is_paired_end {
    -            id2  = buffer_iter.next().expect("ERROR reading the ID line")
    -                .expect("ERROR reading the ID line");
    -            seq2 = buffer_iter.next().expect("ERROR reading a sequence line")
    -                .expect("ERROR reading a sequence line");
    -                       buffer_iter.next().expect("ERROR reading a plus line")
    -                          .expect("ERROR reading the plus line");
    -            qual2= buffer_iter.next().expect("ERROR reading a qual line")
    -                .expect("ERROR reading a qual line");
    +            id2  = buffer_iter.next().expect("ERROR reading the ID line")
    +                .expect("ERROR reading the ID line");
    +            seq2 = buffer_iter.next().expect("ERROR reading a sequence line")
    +                .expect("ERROR reading a sequence line");
    +                       buffer_iter.next().expect("ERROR reading a plus line")
    +                          .expect("ERROR reading the plus line");
    +            qual2= buffer_iter.next().expect("ERROR reading a qual line")
    +                .expect("ERROR reading a qual line");
     
                 all_id.push_str(&id2);
                 all_seq.push_str(&seq2);
    @@ -328,32 +330,32 @@
             let tx2          = tx.clone();
             pool.execute(move|| {
               let regex = Regex::new(&regex_param2)
    -              .expect("malformed seq regex within thread, given by --regex");
    -          // Print if it's a match
    +              .expect("malformed seq regex within thread, given by --regex");
    +          // Print if it's a match
               let should_print:bool = match the_field.as_str(){
    -            "SEQ" => {
    +            "SEQ" => {
                     regex.is_match(&all_seq)
                 },
    -            "ID" => {
    +            "ID" => {
                     regex.is_match(&all_id)
                 },
    -            "QUAL" => {
    +            "QUAL" => {
                     regex.is_match(&all_qual)
                 },
                 _ => {
    -              panic!("{} is not a valid key to match on", &the_field);
    +              panic!("{} is not a valid key to match on", &the_field);
                 }
               };
     
                     
               if should_print {
                 if is_paired_end {
    -              tx2.send(format!("{}\n{}\n+\n{}\n{}\n{}\n+\n{}",
    +              tx2.send(format!("{}\n{}\n+\n{}\n{}\n{}\n+\n{}",
                     id, seq, qual,
                     id2,seq2,qual2
                   )).unwrap();
                 } else {
    -              tx2.send(format!("{}\n{}\n+\n{}",
    +              tx2.send(format!("{}\n{}\n+\n{}",
                     id, seq, qual
                   )).unwrap();
                 }
    @@ -366,7 +368,7 @@
         // TODO why not make this a separate thread
         let receiver = rx.iter();
         for entry in receiver {
    -      println!("{}",entry);
    +      println!("{}",entry);
         }
     }
     
    diff --git a/docs/src/fasten_repair/fasten_repair.rs.html b/docs/src/fasten_repair/fasten_repair.rs.html
    index bf634074..35d90f6f 100644
    --- a/docs/src/fasten_repair/fasten_repair.rs.html
    +++ b/docs/src/fasten_repair/fasten_repair.rs.html
    @@ -1,4 +1,6 @@
    -fasten_repair.rs - source
    1
    +fasten_repair.rs - source
    +    
    1
     2
     3
     4
    @@ -377,43 +379,43 @@
     fn main(){
         let mut opts = fasten_base_options();
         // Options specific to this script
    -    opts.optopt("","min-length","Minimum read length allowed","INT");
    -    opts.optopt("","min-quality","Minimum quality allowed","FLOAT");
    -    opts.optflag("", "remove-info", "Remove fasten_inspect headers");
    -    opts.optopt("m", "mode", " Either repair or panic. If panic, then the binary will panic when the first issue comes up. Default:repair", "STRING");
    +    opts.optopt("","min-length","Minimum read length allowed","INT");
    +    opts.optopt("","min-quality","Minimum quality allowed","FLOAT");
    +    opts.optflag("", "remove-info", "Remove fasten_inspect headers");
    +    opts.optopt("m", "mode", " Either repair or panic. If panic, then the binary will panic when the first issue comes up. Default:repair", "STRING");
     
    -    let matches = fasten_base_options_matches("Repairs reads", opts);
    +    let matches = fasten_base_options_matches("Repairs reads", opts);
     
    -    let paired_end = matches.opt_present("paired-end");
    +    let paired_end = matches.opt_present("paired-end");
     
         let min_length :usize={
    -        if matches.opt_present("min-length") {
    -            matches.opt_str("min-length")
    -                .expect("ERROR parsing min-length")
    +        if matches.opt_present("min-length") {
    +            matches.opt_str("min-length")
    +                .expect("ERROR parsing min-length")
                     .parse()
    -                .expect("ERROR parsing min-length as INT")
    +                .expect("ERROR parsing min-length as INT")
             } else {
                 0
             }
         };
         let min_qual :f32={
    -        if matches.opt_present("min-quality") {
    -            matches.opt_str("min-quality")
    -                .expect("ERROR parsing min-quality")
    +        if matches.opt_present("min-quality") {
    +            matches.opt_str("min-quality")
    +                .expect("ERROR parsing min-quality")
                     .parse()
    -                .expect("ERROR parsing min-quality as FLOAT")
    +                .expect("ERROR parsing min-quality as FLOAT")
             } else {
                 0.0
             }
         };
     
    -    let remove_info :bool = matches.opt_present("remove-info");
    +    let remove_info :bool = matches.opt_present("remove-info");
         let mode :String = {
    -        if matches.opt_present("mode") {
    -            matches.opt_str("mode")
    -                .expect("ERROR parsing mode")
    +        if matches.opt_present("mode") {
    +            matches.opt_str("mode")
    +                .expect("ERROR parsing mode")
             } else {
    -            "repair".to_string()
    +            "repair".to_string()
             }
         };
     
    @@ -424,14 +426,14 @@
     fn repair_reads(paired_end:bool, min_length: usize, min_qual: f32, remove_info: bool, mode: &str) {
         //behavior
         let should_repair :bool = {
    -        if mode == "repair" {
    +        if mode == "repair" {
                 true
             } else {
                 false
             }
         };
     
    -    let my_file = File::open("/dev/stdin").expect("Could not open file");
    +    let my_file = File::open("/dev/stdin").expect("Could not open file");
         let mut my_buffer = BufReader::new(my_file);
     
         let mut id   = String::new();
    @@ -443,17 +445,17 @@
         loop{
     
             id.clear();
    -        if my_buffer.read_line(&mut id).expect("Cannot read new line") == 0 {
    +        if my_buffer.read_line(&mut id).expect("Cannot read new line") == 0 {
                 break;
             }
             let r1_id = id.clone();
             
             seq.clear();
    -        my_buffer.read_line(&mut seq).expect("ERROR: failed to read 'seq' line");
    +        my_buffer.read_line(&mut seq).expect("ERROR: failed to read 'seq' line");
             plus.clear();
    -        my_buffer.read_line(&mut plus).expect("ERROR: failed to read 'plus' line");
    +        my_buffer.read_line(&mut plus).expect("ERROR: failed to read 'plus' line");
             qual.clear();
    -        my_buffer.read_line(&mut qual).expect("ERROR: failed to read 'qual' line");
    +        my_buffer.read_line(&mut qual).expect("ERROR: failed to read 'qual' line");
             id   = id.trim().to_string();
             seq  = seq.trim().to_string();
             plus = plus.trim().to_string();
    @@ -463,22 +465,22 @@
             //i += 4;
     
             let mut is_r2_good = true;
    -        let mut r2 = "".to_string();
    -        let mut err2 = "".to_string();
    -        let mut r2_id :String = "".to_string();
    +        let mut r2 = "".to_string();
    +        let mut err2 = "".to_string();
    +        let mut r2_id :String = "".to_string();
             if paired_end {
                 id.clear();
    -            if my_buffer.read_line(&mut id).expect("Cannot read new line") == 0 {
    -                panic!("ERROR: paired end expected but not found after R1 {}", r1_id);
    +            if my_buffer.read_line(&mut id).expect("Cannot read new line") == 0 {
    +                panic!("ERROR: paired end expected but not found after R1 {}", r1_id);
                 }
                 r2_id = id.clone();
                 
                 seq.clear();
    -            my_buffer.read_line(&mut seq).expect("ERROR: failed to read 'seq' line");
    +            my_buffer.read_line(&mut seq).expect("ERROR: failed to read 'seq' line");
                 plus.clear();
    -            my_buffer.read_line(&mut plus).expect("ERROR: failed to read 'plus' line");
    +            my_buffer.read_line(&mut plus).expect("ERROR: failed to read 'plus' line");
                 qual.clear();
    -            my_buffer.read_line(&mut qual).expect("ERROR: failed to read 'qual' line");
    +            my_buffer.read_line(&mut qual).expect("ERROR: failed to read 'qual' line");
                 id   = id.trim().to_string();
                 seq  = seq.trim().to_string();
                 plus = plus.trim().to_string();
    @@ -490,29 +492,29 @@
             if is_r1_good && is_r2_good{
                 // Start with R1 for printing.
                 let mut to_print = r1.clone();
    -            // If we're looking at a paired end, then add R2 to R1 for printing.
    +            // If we're looking at a paired end, then add R2 to R1 for printing.
                 if paired_end {
    -                to_print.push_str("\n");
    +                to_print.push_str("\n");
                     to_print.push_str(&r2);
                 } 
    -            println!("{}", to_print);
    +            println!("{}", to_print);
     
    -            // If R1 and R2 are good, then any "errors" are warnings.
    +            // If R1 and R2 are good, then any "errors" are warnings.
                 // Print the warnings.
    -            if err1.as_str() != "" {
    -                logmsg(format!("WARNING(s) on R1: {}", err1));
    +            if err1.as_str() != "" {
    +                logmsg(format!("WARNING(s) on R1: {}", err1));
                 }
    -            if err2.as_str() != "" {
    -                logmsg(format!("WARNING(s) on R2: {}", err2));
    +            if err2.as_str() != "" {
    +                logmsg(format!("WARNING(s) on R2: {}", err2));
                 }
             } else {
                 
                 // Print the errors.
    -            if err1.as_str() != "" {
    -                logmsg(format!("SKIP R1 {}\n=> {}\n", r1_id.trim(), err1));
    +            if err1.as_str() != "" {
    +                logmsg(format!("SKIP R1 {}\n=> {}\n", r1_id.trim(), err1));
                 }
    -            if err2.as_str() != "" {
    -                logmsg(format!("SKIP R2 {}\n=> {}\n", r2_id.trim(), err2));
    +            if err2.as_str() != "" {
    +                logmsg(format!("SKIP R2 {}\n=> {}\n", r2_id.trim(), err2));
                 }
             }
         }
    @@ -530,29 +532,29 @@
         let mut f:HashMap<&str, &str> = HashMap::new();
         // Get that information from the defline
         for field in id.split_whitespace() {
    -        match field.find(":") {
    +        match field.find(":") {
                 None => {
                     identifier.push_str(&field);
                     continue;
                 },
                 Some(_) => {},
             };
    -        let mut key_value = field.split(':');
    -        let key   :&str = key_value.next().expect("key not found");
    -        let value :&str = key_value.next().expect("value not found");
    +        let mut key_value = field.split(':');
    +        let key   :&str = key_value.next().expect("key not found");
    +        let value :&str = key_value.next().expect("value not found");
             f.insert(key, value);
         }
     
         // get some variables out of the hash
    -    let seq_length  :usize = f.entry("seq-length").or_insert("0").parse::<usize>().unwrap();
    -    let qual_length :usize = f.entry("qual-length").or_insert("0").parse::<usize>().unwrap();
    -    let avg_qual    :f32   = f.entry("avg-qual").or_insert("0").parse::<f32>().unwrap();
    -    let seq_invalid_chars :&str  = f.entry("seq-invalid-chars").or_insert("");
    -    let qual_invalid_chars :&str = f.entry("qual-invalid-chars").or_insert("");
    -    let _read_pair :u8 = f.entry("read-pair").or_insert("1").parse::<u8>().unwrap(); // either 1 or 2
    +    let seq_length  :usize = f.entry("seq-length").or_insert("0").parse::<usize>().unwrap();
    +    let qual_length :usize = f.entry("qual-length").or_insert("0").parse::<usize>().unwrap();
    +    let avg_qual    :f32   = f.entry("avg-qual").or_insert("0").parse::<f32>().unwrap();
    +    let seq_invalid_chars :&str  = f.entry("seq-invalid-chars").or_insert("");
    +    let qual_invalid_chars :&str = f.entry("qual-invalid-chars").or_insert("");
    +    let _read_pair :u8 = f.entry("read-pair").or_insert("1").parse::<u8>().unwrap(); // either 1 or 2
         // these are either 1 (true) or 0 (false)
    -    let id_at :u8 = f.entry("id-at").or_insert("0").parse::<u8>().unwrap();
    -    let id_plus :u8 = f.entry("id-plus").or_insert("0").parse::<u8>().unwrap();
    +    let id_at :u8 = f.entry("id-at").or_insert("0").parse::<u8>().unwrap();
    +    let id_plus :u8 = f.entry("id-plus").or_insert("0").parse::<u8>().unwrap();
     
         // Check seq length and qual length
         if seq_length != qual_length {
    @@ -561,38 +563,38 @@
                 seq  = seq[..new_length].to_string();
                 qual = qual[..new_length].to_string();
                 error.push_str(
    -                &format!("Repaired sequence and qual length\n")
    +                &format!("Repaired sequence and qual length\n")
                 );
    -            // Don't count this as an actual error and so don't increment.
    +            // Don't count this as an actual error and so don't increment.
             } else {
    -            panic!("ERROR: seq length({}) did not match qual length({}) on seqid {}\n", &seq_length, &qual_length, &id);
    +            panic!("ERROR: seq length({}) did not match qual length({}) on seqid {}\n", &seq_length, &qual_length, &id);
             }
         }
         if seq_length < min_length {
             error.push_str(
    -            &format!("seq length({}) is less than min length specified ({})\n", &seq_length, &min_length)
    +            &format!("seq length({}) is less than min length specified ({})\n", &seq_length, &min_length)
             );
             num_errors += 1;
         }
         // Check quality score
         if avg_qual < min_qual {
             error.push_str(
    -            &format!("average quality ({}) is less than min quality ({})\n", &avg_qual, &min_qual)
    +            &format!("average quality ({}) is less than min quality ({})\n", &avg_qual, &min_qual)
             );
             num_errors += 1;
         }
     
         // check key seq-invalid-chars
    -    if seq_invalid_chars != "" {
    +    if seq_invalid_chars != "" {
             error.push_str(
    -            &format!("invalid seq characters found in {}\n", &id)
    +            &format!("invalid seq characters found in {}\n", &id)
             );
             num_errors += 1;
         }
         // check key qual-invalid-chars
    -    if qual_invalid_chars != "" {
    +    if qual_invalid_chars != "" {
             error.push_str(
    -            &format!("invalid qual characters found in {}\n", &id)
    +            &format!("invalid qual characters found in {}\n", &id)
             );
             num_errors += 1;
         }
    @@ -600,14 +602,14 @@
         // check key id-at
         if id_at < 1 {
             error.push_str(
    -            &format!("no @ found at position 1 on line 1 for {}\n", &id)
    +            &format!("no @ found at position 1 on line 1 for {}\n", &id)
             );    
             num_errors += 1;
         }
         // check key id-plus 
         if id_plus < 1 {
             error.push_str(
    -            &format!("no + found at position 1 on line 3 for {}\n", &id)
    +            &format!("no + found at position 1 on line 3 for {}\n", &id)
             );
             num_errors += 1;
         }
    @@ -617,7 +619,7 @@
             id = identifier.clone();
         }
         
    -    let entry :String = format!("{}\n{}\n{}\n{}", &id, &seq, &plus, &qual);
    +    let entry :String = format!("{}\n{}\n{}\n{}", &id, &seq, &plus, &qual);
     
         let mut is_good = true;
         if num_errors > 0 {
    diff --git a/docs/src/fasten_replace/fasten_replace.rs.html b/docs/src/fasten_replace/fasten_replace.rs.html
    index 18c0dbd0..969def8d 100644
    --- a/docs/src/fasten_replace/fasten_replace.rs.html
    +++ b/docs/src/fasten_replace/fasten_replace.rs.html
    @@ -1,4 +1,6 @@
    -fasten_replace.rs - source
    1
    +fasten_replace.rs - source
    +    
    1
     2
     3
     4
    @@ -138,7 +140,7 @@
     //!     -n, --numcpus INT   Number of CPUs (default: 1)
     //!     -p, --paired-end    The input reads are interleaved paired-end
     //!     -v, --verbose       Print more status messages
    -//!     -f, --find STRING   Regular expression (default: '.')
    +//!     -f, --find STRING   Regular expression (default: '.')
     //!     -r, --replace STRING
     //!                         String to replace each match
     //!     -w, --which STRING  Which field to match on? ID, SEQ, QUAL. Default: SEQ
    @@ -159,75 +161,75 @@
     fn main(){
         let mut opts = fasten_base_options();
         // Options specific to this script
    -    opts.optopt("f","find","Regular expression (default: '.')","STRING");
    -    opts.optopt("r","replace","String to replace each match","STRING");
    -    opts.optopt("w","which","Which field to match on? ID, SEQ, QUAL. Default: SEQ","STRING");
    +    opts.optopt("f","find","Regular expression (default: '.')","STRING");
    +    opts.optopt("r","replace","String to replace each match","STRING");
    +    opts.optopt("w","which","Which field to match on? ID, SEQ, QUAL. Default: SEQ","STRING");
     
    -    let matches = fasten_base_options_matches("Streaming editor for fastq data using a find/replace.", opts);
    +    let matches = fasten_base_options_matches("Streaming editor for fastq data using a find/replace.", opts);
     
    -    if matches.opt_present("paired-end") {
    -        logmsg("WARNING: --paired-end is not utilized in this script");
    +    if matches.opt_present("paired-end") {
    +        logmsg("WARNING: --paired-end is not utilized in this script");
         }
     
         //which field does the user want to find and replace?
         let which_field={
    -        if matches.opt_present("which") {
    -            matches.opt_str("which").expect("ERROR parsing --which")
    +        if matches.opt_present("which") {
    +            matches.opt_str("which").expect("ERROR parsing --which")
                     .to_uppercase()
             } else {
    -            "SEQ".to_string()
    +            "SEQ".to_string()
             }
         };
     
         // Figure out what we are searching for
         let find_param={
    -        if matches.opt_present("find") {
    -            matches.opt_str("find")
    -                .expect("ERROR: could not parse find parameter")
    +        if matches.opt_present("find") {
    +            matches.opt_str("find")
    +                .expect("ERROR: could not parse find parameter")
             } else {
    -            String::from(".")
    +            String::from(".")
             }
         };
     
         // form the regex
         let find_regex = Regex::new(&find_param)
    -        .expect("malformed seq regex given by --find");
    +        .expect("malformed seq regex given by --find");
     
         // Make the replace string
         let replace :String = {
    -        if matches.opt_present("replace") {
    -            matches.opt_str("replace")
    -                .expect("ERROR: could not parse --replace parameter")
    +        if matches.opt_present("replace") {
    +            matches.opt_str("replace")
    +                .expect("ERROR: could not parse --replace parameter")
             } else {
    -            String::from("")
    +            String::from("")
             }
         };
         // but it requires a &str
         let replace_str :&str = replace.as_str();
     
    -    let my_file = File::open("/dev/stdin").expect("Could not open file");
    +    let my_file = File::open("/dev/stdin").expect("Could not open file");
         let my_buffer=BufReader::new(my_file);
         let mut buffer_iter = my_buffer.lines();
         while let Some(line) = buffer_iter.next() {
    -        let mut id  = line.expect("ERROR reading the ID line");
    -        let mut seq = buffer_iter.next().expect("ERROR reading a sequence line")
    -            .expect("ERROR reading a sequence line");
    -                  buffer_iter.next().expect("ERROR reading a plus line")
    -                      .expect("ERROR reading the plus line");
    -        let mut qual= buffer_iter.next().expect("ERROR reading a qual line")
    -            .expect("ERROR reading a qual line");
    +        let mut id  = line.expect("ERROR reading the ID line");
    +        let mut seq = buffer_iter.next().expect("ERROR reading a sequence line")
    +            .expect("ERROR reading a sequence line");
    +                  buffer_iter.next().expect("ERROR reading a plus line")
    +                      .expect("ERROR reading the plus line");
    +        let mut qual= buffer_iter.next().expect("ERROR reading a qual line")
    +            .expect("ERROR reading a qual line");
     
             // Find and replace
    -        if &which_field == "SEQ" {
    +        if &which_field == "SEQ" {
                 seq  = find_regex.replace_all(&seq, replace_str).into_owned();
    -        } else if &which_field == "QUAL" {
    +        } else if &which_field == "QUAL" {
                 qual = find_regex.replace_all(&qual, replace_str).into_owned();
    -        } else if &which_field == "ID" {
    +        } else if &which_field == "ID" {
                 id   = find_regex.replace_all(&id, replace_str).into_owned();
             } else {
    -            panic!("Not implemented for --which: {}", which_field);
    +            panic!("Not implemented for --which: {}", which_field);
             }
    -        println!("{}\n{}\n+\n{}",id,seq,qual);
    +        println!("{}\n{}\n+\n{}",id,seq,qual);
     
         }
     }
    diff --git a/docs/src/fasten_sample/fasten_sample.rs.html b/docs/src/fasten_sample/fasten_sample.rs.html
    index 54005973..4673e52b 100644
    --- a/docs/src/fasten_sample/fasten_sample.rs.html
    +++ b/docs/src/fasten_sample/fasten_sample.rs.html
    @@ -1,4 +1,6 @@
    -fasten_sample.rs - source
    1
    +fasten_sample.rs - source
    +    
    1
     2
     3
     4
    @@ -138,40 +140,40 @@
     fn main(){
         let mut opts = fasten_base_options();
     
    -    opts.optopt("f","frequency","Frequency of sequences to print, 0 to 1. Default: 1","FLOAT");
    +    opts.optopt("f","frequency","Frequency of sequences to print, 0 to 1. Default: 1","FLOAT");
     
    -    let matches = fasten_base_options_matches("Downsample your reads", opts);
    +    let matches = fasten_base_options_matches("Downsample your reads", opts);
     
         let frequency :f32 = {
    -        if matches.opt_present("frequency") {
    -            matches.opt_str("frequency")
    -            .expect("ERROR parsing frequency parameter")
    +        if matches.opt_present("frequency") {
    +            matches.opt_str("frequency")
    +            .expect("ERROR parsing frequency parameter")
                 .parse()
    -            .expect("ERROR parsing frequency as a float")
    +            .expect("ERROR parsing frequency as a float")
             } else {
                 1.0
             }
         };
     
         let lines_per_read={
    -        if matches.opt_present("paired-end") {
    +        if matches.opt_present("paired-end") {
                 8
             }else{
                 4
             }
         };
     
    -    let my_file = File::open("/dev/stdin").expect("Could not open file");
    +    let my_file = File::open("/dev/stdin").expect("Could not open file");
         let my_buffer=BufReader::new(my_file);
         let mut line_counter =0;
         let mut entry = String::new();
         let mut randoms :Vec<f32> = vec![];
         for line in my_buffer.lines() {
             // unwrap the line here and shadow-set the variable.
    -        let line=line.expect("ERROR: did not get a line");
    +        let line=line.expect("ERROR: did not get a line");
             line_counter+=1;
             entry.push_str(&line);
    -        entry.push_str("\n");
    +        entry.push_str("\n");
     
             // Action if we have a full entry when mod 0
             if line_counter % lines_per_read == 0 {
    @@ -181,7 +183,7 @@
                 let r:f32 = randoms.pop().unwrap();
                 // Should we print?
                 if r < frequency {
    -                print!("{}",entry);
    +                print!("{}",entry);
                 }
                 // reset the entry string
                 entry = String::new();
    diff --git a/docs/src/fasten_shuffle/fasten_shuffle.rs.html b/docs/src/fasten_shuffle/fasten_shuffle.rs.html
    index 717e1735..1cbcdf64 100644
    --- a/docs/src/fasten_shuffle/fasten_shuffle.rs.html
    +++ b/docs/src/fasten_shuffle/fasten_shuffle.rs.html
    @@ -1,4 +1,6 @@
    -fasten_shuffle.rs - source
    1
    +fasten_shuffle.rs - source
    +    
    1
     2
     3
     4
    @@ -238,17 +240,17 @@
     fn main(){
         let mut opts = fasten_base_options();
         //script-specific flags
    -    opts.optflag("d","deshuffle","Deshuffle reads from stdin");
    -    opts.optopt("1","","Forward reads. If deshuffling, reads are written to this file.","1.fastq");
    -    opts.optopt("2","","Forward reads. If deshuffling, reads are written to this file.","2.fastq");
    +    opts.optflag("d","deshuffle","Deshuffle reads from stdin");
    +    opts.optopt("1","","Forward reads. If deshuffling, reads are written to this file.","1.fastq");
    +    opts.optopt("2","","Forward reads. If deshuffling, reads are written to this file.","2.fastq");
     
    -    let matches = fasten_base_options_matches("Interleaves reads from either stdin or file parameters", opts);
    +    let matches = fasten_base_options_matches("Interleaves reads from either stdin or file parameters", opts);
         
    -    if matches.opt_present("paired-end") {
    -        logmsg("WARNING: --paired-end was supplied but it is assumed for this script anyway");
    +    if matches.opt_present("paired-end") {
    +        logmsg("WARNING: --paired-end was supplied but it is assumed for this script anyway");
         }
     
    -    if matches.opt_present("deshuffle") {
    +    if matches.opt_present("deshuffle") {
             deshuffle(&matches);
         } else {
             shuffle(&matches);
    @@ -259,22 +261,22 @@
     fn deshuffle(matches: &getopts::Matches) -> () {
         
         // Where are we reading to?  Get those filenames.
    -    let r1_filename = if matches.opt_present("1") {
    -        matches.opt_str("1").unwrap()
    +    let r1_filename = if matches.opt_present("1") {
    +        matches.opt_str("1").unwrap()
         } else {
    -        "/dev/stdout".to_string()
    +        "/dev/stdout".to_string()
         };
    -    let r2_filename = if matches.opt_present("2") {
    -        matches.opt_str("2").unwrap()
    +    let r2_filename = if matches.opt_present("2") {
    +        matches.opt_str("2").unwrap()
         } else {
    -        "/dev/stdout".to_string()
    +        "/dev/stdout".to_string()
         };
     
    -    let mut file1 = File::create(r1_filename).expect("ERROR: could not write to file");
    -    let mut file2 = File::create(r2_filename).expect("ERROR: could not write to file");
    +    let mut file1 = File::create(r1_filename).expect("ERROR: could not write to file");
    +    let mut file2 = File::create(r2_filename).expect("ERROR: could not write to file");
     
         // read stdin
    -    let my_file = File::open("/dev/stdin").expect("Could not open file");
    +    let my_file = File::open("/dev/stdin").expect("Could not open file");
         let my_buffer=BufReader::new(my_file);
         let fastq_reader=fastq::FastqReader::new(my_buffer);
         let mut read_counter=0;
    @@ -282,9 +284,9 @@
             
             // print to file 1 and to file 2, alternating each Seq
             if read_counter % 2 == 0 {
    -            write!(file1,"{}\n",seq.to_string()).unwrap();
    +            write!(file1,"{}\n",seq.to_string()).unwrap();
             } else {
    -            write!(file2,"{}\n",seq.to_string()).unwrap();
    +            write!(file2,"{}\n",seq.to_string()).unwrap();
             }
             read_counter+=1;
         }
    @@ -295,15 +297,15 @@
     fn shuffle(matches: &getopts::Matches) -> () {
     
         // Where are we reading from?  Get those filenames.
    -    let r1_filename = if matches.opt_present("1") {
    -        matches.opt_str("1").unwrap()
    +    let r1_filename = if matches.opt_present("1") {
    +        matches.opt_str("1").unwrap()
         } else {
    -        "/dev/stdin".to_string()
    +        "/dev/stdin".to_string()
         };
    -    let r2_filename = if matches.opt_present("2") {
    -        matches.opt_str("2").unwrap()
    +    let r2_filename = if matches.opt_present("2") {
    +        matches.opt_str("2").unwrap()
         } else {
    -        "/dev/stdin".to_string()
    +        "/dev/stdin".to_string()
         };
     
         // Read 1 first, and read 2 is halfway down.
    @@ -323,8 +325,8 @@
             let mut seq_idx = 0;
             while seq_idx < num_pairs {
                 if seq_idx + num_pairs >= seqs_all.len() {
    -                logmsg("Looks like one of the R2 reads is missing. Skipping an R1/R2 pair.");
    -                logmsg("If this is in error, please see fasten_validate --paired-ends");
    +                logmsg("Looks like one of the R2 reads is missing. Skipping an R1/R2 pair.");
    +                logmsg("If this is in error, please see fasten_validate --paired-ends");
                     num_pairs = seq_idx;
                     break;
                 }
    @@ -346,7 +348,7 @@
     /// Read fastq entries from a filename
     fn read_seqs(filename: &String) -> Vec<Seq> {
     
    -    let my_file = File::open(&filename).expect("Could not open file");
    +    let my_file = File::open(&filename).expect("Could not open file");
         let my_buffer=BufReader::new(my_file);
         let fastq_reader=fastq::FastqReader::new(my_buffer);
         let seqs :Vec<Seq> = fastq_reader.collect();
    diff --git a/docs/src/fasten_sort/fasten_sort.rs.html b/docs/src/fasten_sort/fasten_sort.rs.html
    index feb7c454..58b24c1d 100644
    --- a/docs/src/fasten_sort/fasten_sort.rs.html
    +++ b/docs/src/fasten_sort/fasten_sort.rs.html
    @@ -1,4 +1,6 @@
    -fasten_sort.rs - source
    1
    +fasten_sort.rs - source
    +    
    1
     2
     3
     4
    @@ -335,20 +337,20 @@
     #[test]
     fn test_sort_fastq_basic () {
         let is_paired_end = false;
    -    let which_field   = "ID";
    -    let my_file = File::open("testdata/four_reads.fastq").expect("Could not open file");
    +    let which_field   = "ID";
    +    let my_file = File::open("testdata/four_reads.fastq").expect("Could not open file");
         let my_buffer=BufReader::new(my_file);
         let mut buffer_iter = my_buffer.lines();
     
         let mut entries:Vec<Seq> = vec![];
         while let Some(line) = buffer_iter.next() {
    -        let id1  = line.expect("ERROR reading the ID line");
    -        let seq1 = buffer_iter.next().expect("ERROR reading a sequence line")
    -            .expect("ERROR reading a sequence line");
    -                  buffer_iter.next().expect("ERROR reading a plus line")
    -                      .expect("ERROR reading the plus line");
    -        let qual1= buffer_iter.next().expect("ERROR reading a qual line")
    -            .expect("ERROR reading a qual line");
    +        let id1  = line.expect("ERROR reading the ID line");
    +        let seq1 = buffer_iter.next().expect("ERROR reading a sequence line")
    +            .expect("ERROR reading a sequence line");
    +                  buffer_iter.next().expect("ERROR reading a plus line")
    +                      .expect("ERROR reading the plus line");
    +        let qual1= buffer_iter.next().expect("ERROR reading a qual line")
    +            .expect("ERROR reading a qual line");
     
             let mut id2   =String::new();
             let mut seq2  =String::new();
    @@ -356,14 +358,14 @@
     
             // Get R2
             if is_paired_end {
    -            id2  = buffer_iter.next().expect("ERROR reading the ID line")
    -                .expect("ERROR reading the ID line");
    -            seq2 = buffer_iter.next().expect("ERROR reading a sequence line")
    -                .expect("ERROR reading a sequence line");
    -                       buffer_iter.next().expect("ERROR reading a plus line")
    -                          .expect("ERROR reading the plus line");
    -            qual2= buffer_iter.next().expect("ERROR reading a qual line")
    -                .expect("ERROR reading a qual line");
    +            id2  = buffer_iter.next().expect("ERROR reading the ID line")
    +                .expect("ERROR reading the ID line");
    +            seq2 = buffer_iter.next().expect("ERROR reading a sequence line")
    +                .expect("ERROR reading a sequence line");
    +                       buffer_iter.next().expect("ERROR reading a plus line")
    +                          .expect("ERROR reading the plus line");
    +            qual2= buffer_iter.next().expect("ERROR reading a qual line")
    +                .expect("ERROR reading a qual line");
             }
     
             let entry:Seq = Seq {
    @@ -383,16 +385,16 @@
         // test that each read is readX in a sorted order
         let sorted_entries:Vec<Seq> = sort_entries(entries.clone(), &which_field, false);
         for i in 0..4 {
    -        let expected = format!("@read{}",i);
    -        assert_eq!(sorted_entries[i].id1, expected, "Sort by ID");
    +        let expected = format!("@read{}",i);
    +        assert_eq!(sorted_entries[i].id1, expected, "Sort by ID");
         }
     
         // test reverse sorting
         let reverse_sorted_entries:Vec<Seq> = sort_entries(entries.clone(), &which_field, true);
         for i in 0..4 {
    -        let expected = format!("@read{}",i);
    +        let expected = format!("@read{}",i);
             let idx = 3 - i;
    -        assert_eq!(reverse_sorted_entries[idx].id1, expected, "Reverse sort by ID. Full list is {:?}", reverse_sorted_entries);
    +        assert_eq!(reverse_sorted_entries[idx].id1, expected, "Reverse sort by ID. Full list is {:?}", reverse_sorted_entries);
         }
     }
     
    @@ -411,31 +413,31 @@
     fn main(){
         let mut opts = fasten_base_options();
         // Options specific to this script
    -    opts.optopt("s","sort-by","Sort by either SEQ, GC, or ID. If GC, then the entries are sorted by GC percentage. SEQ and ID are alphabetically sorted.","STRING");
    -    opts.optflag("r","reverse","Reverse sort");
    +    opts.optopt("s","sort-by","Sort by either SEQ, GC, or ID. If GC, then the entries are sorted by GC percentage. SEQ and ID are alphabetically sorted.","STRING");
    +    opts.optflag("r","reverse","Reverse sort");
     
    -    let matches = fasten_base_options_matches("Sort reads. This can be useful for many things including checksums and reducing gzip file sizes. Remember to use --paired-end if applicable.", opts);
    +    let matches = fasten_base_options_matches("Sort reads. This can be useful for many things including checksums and reducing gzip file sizes. Remember to use --paired-end if applicable.", opts);
     
    -    let my_file = File::open("/dev/stdin").expect("Could not open file");
    +    let my_file = File::open("/dev/stdin").expect("Could not open file");
         let my_buffer=BufReader::new(my_file);
     
    -    let is_paired_end=matches.opt_present("paired-end");
    -    let reverse_sort =matches.opt_present("reverse");
    +    let is_paired_end=matches.opt_present("paired-end");
    +    let reverse_sort =matches.opt_present("reverse");
     
         let which_field:String={
    -        if matches.opt_present("sort-by") {
    -            matches.opt_str("sort-by").expect("ERROR parsing --sort-by")
    +        if matches.opt_present("sort-by") {
    +            matches.opt_str("sort-by").expect("ERROR parsing --sort-by")
                     .to_uppercase()
             } else {
    -            "ID".to_string()
    +            "ID".to_string()
             }
         };
     
         let _num_cpus:usize = {
    -        if matches.opt_present("numcpus") {
    -            matches.opt_str("numcpus").expect("ERROR parsing --numcpus")
    +        if matches.opt_present("numcpus") {
    +            matches.opt_str("numcpus").expect("ERROR parsing --numcpus")
                     .parse()
    -                .expect("ERROR: numcpus is not an integer")
    +                .expect("ERROR: numcpus is not an integer")
             } else {
                 1
             }
    @@ -445,13 +447,13 @@
     
         let mut entries:Vec<Seq> = vec![];
         while let Some(line) = buffer_iter.next() {
    -        let id1  = line.expect("ERROR reading the ID line");
    -        let seq1 = buffer_iter.next().expect("ERROR reading a sequence line")
    -            .expect("ERROR reading a sequence line");
    -                  buffer_iter.next().expect("ERROR reading a plus line")
    -                      .expect("ERROR reading the plus line");
    -        let qual1= buffer_iter.next().expect("ERROR reading a qual line")
    -            .expect("ERROR reading a qual line");
    +        let id1  = line.expect("ERROR reading the ID line");
    +        let seq1 = buffer_iter.next().expect("ERROR reading a sequence line")
    +            .expect("ERROR reading a sequence line");
    +                  buffer_iter.next().expect("ERROR reading a plus line")
    +                      .expect("ERROR reading the plus line");
    +        let qual1= buffer_iter.next().expect("ERROR reading a qual line")
    +            .expect("ERROR reading a qual line");
     
             let mut id2   =String::new();
             let mut seq2  =String::new();
    @@ -459,14 +461,14 @@
     
             // Get R2
             if is_paired_end {
    -            id2  = buffer_iter.next().expect("ERROR reading the ID line")
    -                .expect("ERROR reading the ID line");
    -            seq2 = buffer_iter.next().expect("ERROR reading a sequence line")
    -                .expect("ERROR reading a sequence line");
    -                       buffer_iter.next().expect("ERROR reading a plus line")
    -                          .expect("ERROR reading the plus line");
    -            qual2= buffer_iter.next().expect("ERROR reading a qual line")
    -                .expect("ERROR reading a qual line");
    +            id2  = buffer_iter.next().expect("ERROR reading the ID line")
    +                .expect("ERROR reading the ID line");
    +            seq2 = buffer_iter.next().expect("ERROR reading a sequence line")
    +                .expect("ERROR reading a sequence line");
    +                       buffer_iter.next().expect("ERROR reading a plus line")
    +                          .expect("ERROR reading the plus line");
    +            qual2= buffer_iter.next().expect("ERROR reading a qual line")
    +                .expect("ERROR reading a qual line");
             }
     
             let entry:Seq = Seq {
    @@ -485,9 +487,9 @@
     
         let sorted_entries:Vec<Seq> = sort_entries(entries, &which_field, reverse_sort);
         for entry in sorted_entries {
    -        println!("{}\n{}\n+\n{}", entry.id1, entry.seq1, entry.qual1);
    +        println!("{}\n{}\n+\n{}", entry.id1, entry.seq1, entry.qual1);
             if entry.pe {
    -            println!("{}\n{}\n+\n{}", entry.id2, entry.seq2, entry.qual2);
    +            println!("{}\n{}\n+\n{}", entry.id2, entry.seq2, entry.qual2);
             }
         }
     
    @@ -496,7 +498,7 @@
     /// Sort fastq entries in a vector
     fn sort_entries (unsorted:Vec<Seq>, which_field:&str, reverse_sort:bool) -> Vec<Seq> {
     
    -    //logmsg(&format!("REVERSE SORT? {}\n{:?}",reverse_sort, &unsorted));
    +    //logmsg(&format!("REVERSE SORT? {}\n{:?}",reverse_sort, &unsorted));
     
         // I want to avoid editing the vector in place
         let mut sorted = unsorted.clone();
    @@ -504,38 +506,38 @@
         // Actual sort
         // TODO sort by length?
         match which_field{
    -        "ID" => {
    +        "ID" => {
                 sorted.sort_by(|a, b| {
    -                let a_id = format!("{}{}", a.id1, a.id2);
    -                let b_id = format!("{}{}", b.id1, b.id2);
    +                let a_id = format!("{}{}", a.id1, a.id2);
    +                let b_id = format!("{}{}", b.id1, b.id2);
                     a_id.cmp(&b_id)
                 });
             },
    -        "SEQ" => {
    +        "SEQ" => {
                 sorted.sort_by(|a, b| {
    -                let a_seq = format!("{}{}", a.seq1, a.seq2);
    -                let b_seq = format!("{}{}", b.seq1, b.seq2);
    +                let a_seq = format!("{}{}", a.seq1, a.seq2);
    +                let b_seq = format!("{}{}", b.seq1, b.seq2);
                     a_seq.cmp(&b_seq)
                 });
             },
    -        "GC"  => {
    +        "GC"  => {
                 sorted.sort_by(|a,b| {
    -                let a_seq = format!("{}{}", a.seq1, a.seq2);
    -                let b_seq = format!("{}{}", b.seq1, b.seq2);
    +                let a_seq = format!("{}{}", a.seq1, a.seq2);
    +                let b_seq = format!("{}{}", b.seq1, b.seq2);
     
    -                let a_gc:f32  = a_seq.matches(&['G','g','C','c']).count() as f32 / a_seq.len() as f32;
    -                let b_gc:f32  = b_seq.matches(&['G','g','C','c']).count() as f32 / b_seq.len() as f32;
    -                //logmsg(format!("{} ({}) <=> {} ({})", a.id1, a_gc, b.id1, b_gc));
    +                let a_gc:f32  = a_seq.matches(&['G','g','C','c']).count() as f32 / a_seq.len() as f32;
    +                let b_gc:f32  = b_seq.matches(&['G','g','C','c']).count() as f32 / b_seq.len() as f32;
    +                //logmsg(format!("{} ({}) <=> {} ({})", a.id1, a_gc, b.id1, b_gc));
                     a_gc.partial_cmp(&b_gc).unwrap()
                 });
             },
             _   => {
    -            panic!("Tried to sort by {} which is not implemented", which_field);
    +            panic!("Tried to sort by {} which is not implemented", which_field);
             }
         };
     
         if reverse_sort {
    -        //logmsg("REVERSE SORT");
    +        //logmsg("REVERSE SORT");
             sorted.reverse();
         }
     
    diff --git a/docs/src/fasten_straighten/fasten_straighten.rs.html b/docs/src/fasten_straighten/fasten_straighten.rs.html
    index c8f024ac..07278415 100644
    --- a/docs/src/fasten_straighten/fasten_straighten.rs.html
    +++ b/docs/src/fasten_straighten/fasten_straighten.rs.html
    @@ -1,4 +1,6 @@
    -fasten_straighten.rs - source
    1
    +fasten_straighten.rs - source
    +    
    1
     2
     3
     4
    @@ -105,7 +107,7 @@
     /// Test to see whether we read the challenge dataset correctly
     fn challenge_dataset () {
         // Open the difficult file
    -    let challenge_file = File::open("testdata/four_reads.gt_16_lines.fastq").expect("Could not open testdata/four_reads.gt_16_lines.fastq");
    +    let challenge_file = File::open("testdata/four_reads.gt_16_lines.fastq").expect("Could not open testdata/four_reads.gt_16_lines.fastq");
         let challenge_buffer=BufReader::new(challenge_file);
         let challenge_reader=fastq::FastqReader::new_careful(challenge_buffer);
         let mut challenge_string = String::new();
    @@ -114,7 +116,7 @@
         }
     
         // Open the easy file
    -    let easy_file  = File::open("testdata/four_reads.fastq").expect("Could not open testdata/four_reads.fastq");
    +    let easy_file  = File::open("testdata/four_reads.fastq").expect("Could not open testdata/four_reads.fastq");
         let easy_buffer= BufReader::new(easy_file);
         let easy_reader=fastq::FastqReader::new(easy_buffer);
         let mut easy_string = String::new();
    @@ -128,13 +130,13 @@
     
     fn main(){
         let opts = fasten_base_options();
    -    let matches = fasten_base_options_matches("Convert a fastq file to a standard 4-lines-per-entry format", opts);
    +    let matches = fasten_base_options_matches("Convert a fastq file to a standard 4-lines-per-entry format", opts);
         
    -    if matches.opt_present("paired-end") {
    -        logmsg("WARNING: --paired-end is not utilized in this script");
    +    if matches.opt_present("paired-end") {
    +        logmsg("WARNING: --paired-end is not utilized in this script");
         }
     
    -    let my_file = File::open("/dev/stdin").expect("Could not open file");
    +    let my_file = File::open("/dev/stdin").expect("Could not open file");
         let my_buffer=BufReader::new(my_file);
         let fastq_reader=fastq::FastqReader::new_careful(my_buffer);
         for seq in fastq_reader {
    diff --git a/docs/src/fasten_trim/fasten_trim.rs.html b/docs/src/fasten_trim/fasten_trim.rs.html
    index f88a5192..4c0f089f 100644
    --- a/docs/src/fasten_trim/fasten_trim.rs.html
    +++ b/docs/src/fasten_trim/fasten_trim.rs.html
    @@ -1,4 +1,6 @@
    -fasten_trim.rs - source
    1
    +fasten_trim.rs - source
    +    
    1
     2
     3
     4
    @@ -129,20 +131,192 @@
     129
     130
     131
    -
    //! Blunt-end trims using 0-based coordinates
    +132
    +133
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    +141
    +142
    +143
    +144
    +145
    +146
    +147
    +148
    +149
    +150
    +151
    +152
    +153
    +154
    +155
    +156
    +157
    +158
    +159
    +160
    +161
    +162
    +163
    +164
    +165
    +166
    +167
    +168
    +169
    +170
    +171
    +172
    +173
    +174
    +175
    +176
    +177
    +178
    +179
    +180
    +181
    +182
    +183
    +184
    +185
    +186
    +187
    +188
    +189
    +190
    +191
    +192
    +193
    +194
    +195
    +196
    +197
    +198
    +199
    +200
    +201
    +202
    +203
    +204
    +205
    +206
    +207
    +208
    +209
    +210
    +211
    +212
    +213
    +214
    +215
    +216
    +217
    +218
    +219
    +220
    +221
    +222
    +223
    +224
    +225
    +226
    +227
    +228
    +229
    +230
    +231
    +232
    +233
    +234
    +235
    +236
    +237
    +238
    +239
    +240
    +241
    +242
    +243
    +244
    +245
    +246
    +247
    +248
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    +256
    +257
    +258
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    +266
    +267
    +268
    +269
    +270
    +271
    +272
    +273
    +274
    +275
    +276
    +277
    +278
    +279
    +280
    +281
    +
    //! Trims reads using 0-based coordinates
     //! 
     //! # Examples
     //! 
    -//! ## Trim five bases from the right side
    +//! ## Adapters
    +//! 
    +//! ### Download the adapter files
    +//! 
    +//! ```bash
    +//! mkdir -pv $HOME/db
    +//! pushd $HOME/db # step into the db directory
    +//! git clone https://github.com/lskatz/adapterseqs
    +//! ADAPTERS=$(find $HOME/db/adapterseqs -name '*.fa')
    +//! popd # return to the original directory
    +//! ```
    +//! 
    +//! ### Trim the adapters
    +//! 
    +//! ```bash
    +//! cat file.fastq | fasten_trim 
    +//! ```
    +//! 
    +//! ## Blunt-end trim five bases from the right side
    +//! 
     //! ```bash
     //! cat file.fastq | fasten_trim -l -5 > trimmed.fastq
     //! ```
     //!
    -//! ## Keep a maximum of 100bp
    +//! ## Keep a maximum of 100bp with blunt-end trimming on the right side
    +//! 
     //! ```bash
     //! cat file.fastq | fasten_trim -l 99 > trimmed.fastq
     //! ```
    -//! ## Trim 5bp from the left side
    +//! 
    +//! ## Blunt-end trim 5bp from the left side
    +//! 
     //! ```bash
     //! cat file.fastq | fasten_trim -f 4  > trimmed.fastq
     //! ```
    @@ -159,9 +333,24 @@
     //!     -v, --verbose       Print more status messages
     //!     -f, --first-base INT
     //!                         The first base to keep (default: 0)
    -//!     -l, --last-base INT The last base to keep. If negative, counts from the
    -//!                         right. (default: 0)
    +//!     -l, --last-base INT The last base to keep. (default: 0)
     //! ```
    +//! 
    +//! # Notes
    +//! 
    +//! The algorithm is as follows:
    +//! 
    +//! 1. marks the first and last bases for trimming as 0 and the last base, respectively
    +//! 2. if an adapter is found at the beginning of the sequence, then move the marker for where it will be trimmed
    +//! 3. Compare the blunt end suggested trimming against where an adapter might be found and move the marker as the most inward possible
    +//! 4. Trim the sequence and quality strings
    +//! 
    +//! # Output
    +//! 
    +//! The deflines will be altered with a description of the trimming using key=value syntax, separated by spaces, e.g.,
    +//! `@M03235:53:000000000-AHLTD:1:1101:1826:14428 trimmed_adapter_rev=TT trimmed_left=0 trimmed_right=249`
    +//! or for a forward adapter,
    +//! `@M03235:53:000000000-AHLTD:1:1101:1758:14922 trimmed_adapter_fwd=AA trimmed_left=2 trimmed_right=251`
     
     extern crate fasten;
     extern crate statistical;
    @@ -170,11 +359,16 @@
     
     use std::fs::File;
     use std::io::BufReader;
    -use std::cmp::min;
    +use std::cmp::{min,max};
    +use std::process::exit;
    +
    +use std::collections::HashMap;
    +use std::io::BufRead;
     
     use fasten::fasten_base_options;
     use fasten::fasten_base_options_matches;
     use fasten::logmsg;
    +use fasten::reverse_complement;
     use fasten::io::fastq;
     use fasten::io::seq::Seq;
     
    @@ -182,42 +376,75 @@
         let mut opts = fasten_base_options();
     
         // script-specific options
    -    opts.optopt("f","first-base","The first base to keep (default: 0)","INT");
    -    opts.optopt("l","last-base","The last base to keep (default: 0)","INT");
    +    opts.optopt("f","first-base","The first base to keep (default: 0)","INT");
    +    opts.optopt("l","last-base","The last base to keep (default: 0)","INT");
    +    opts.optopt("a","adapterseqs","fasta file of adapters","path/to/file.fa");
     
    -    let matches = fasten_base_options_matches("Blunt-end trims using 0-based coordinates", opts);
    +    let matches = fasten_base_options_matches("Blunt-end trims using 0-based coordinates", opts);
    +
    +    let adapterseqs:String = {
    +        if matches.opt_present("adapterseqs") {
    +            matches.opt_str("adapterseqs")
    +                .expect("ERROR: could not understand parameter --adapterseqs")
    +        } else {
    +            "".to_string()
    +        }
    +    };
    +
    +    // store the adapter sequences as a vector of strings
    +    let mut adapters:Vec<String> = Vec::new();
    +    if matches.opt_present("adapterseqs") && adapterseqs.len() > 0 {
    +        // check that the file path exists
    +        // if not, exit with an error
    +        if !std::path::Path::new(&adapterseqs).exists() {
    +            logmsg(format!("ERROR: adapter file {} does not exist", &adapterseqs));
    +            exit(1);
    +        }
     
    -    let first_base:usize ={
    -        if matches.opt_present("first-base") {
    -            matches.opt_str("first-base")
    -                .expect("ERROR: could not understand parameter --first-base")
    +        // read the adapter sequences from the fasta file
    +        adapters = read_fasta(&adapterseqs)
    +            .values()
    +            .map(|x| x.to_string())
    +            .collect();
    +    }
    +    
    +    //if matches.opt_present("verbose") { 
    +    //    //logmsg(&adapters); 
    +    //    eprintln!("Adapters: {:?}", adapters);
    +    //    exit(3); 
    +    //}
    +
    +    let first_base:usize ={
    +        if matches.opt_present("first-base") {
    +            matches.opt_str("first-base")
    +                .expect("ERROR: could not understand parameter --first-base")
                     .parse()
    -                .expect("ERROR: --first-base is not an INT")
    +                .expect("ERROR: --first-base is not an INT")
             } else {
                 0
             }
         };
     
         let last_base:usize ={
    -        if matches.opt_present("last-base") {
    -            matches.opt_str("last-base")
    -                .expect("ERROR: could not understand parameter --last-base")
    +        if matches.opt_present("last-base") {
    +            matches.opt_str("last-base")
    +                .expect("ERROR: could not understand parameter --last-base")
                     .parse()
    -                .expect("ERROR: --last-base is not an INT")
    +                .expect("ERROR: --last-base is not an INT")
             } else {
                 0
             }
         };
     
         let _num_cpus:usize = {
    -      if matches.opt_present("numcpus") {
    +      if matches.opt_present("numcpus") {
             /*
    -        matches.opt_str("numcpus")
    -            .expect("ERROR: could not understand parameter --numcpus")
    +        matches.opt_str("numcpus")
    +            .expect("ERROR: could not understand parameter --numcpus")
                 .parse()
    -            .expect("ERROR: --numcpus is not an INT");
    +            .expect("ERROR: --numcpus is not an INT");
             */
    -        logmsg("Warning: multithreading this script currently slows it down. Resetting to 1 cpu.  Avoid this warning by not using --numcpus");
    +        logmsg("Warning: multithreading this script currently slows it down. Resetting to 1 cpu.  Avoid this warning by not using --numcpus");
             1 as usize
           } else {
             1 as usize
    @@ -225,39 +452,114 @@
         };
         
         // Read from stdin
    -    let my_file = File::open("/dev/stdin").expect("Could not open file");
    +    let my_file = File::open("/dev/stdin").expect("Could not open file");
         let my_buffer=BufReader::new(my_file);
         let fastq_reader = fastq::FastqReader::new(my_buffer);
         let fastq_iter  = fastq_reader.into_iter();
         for seq in fastq_iter {
     
    -        let trimmed:String = trim_worker(seq, first_base, last_base);
    -        println!("{}", trimmed);
    +        let trimmed:String = trim_worker(seq, first_base, last_base, &adapters);
    +        println!("{}", trimmed);
         }
     }
     
     /// Trim a set of fastq entries and send it to a channel
    -fn trim_worker(seq:Seq, first_base:usize, last_base:usize ) -> String {
    +fn trim_worker(seq:Seq, suggested_first_base:usize, suggested_last_base:usize, adapters:&Vec<String> ) -> String {
     
    +    // In this function, keep track of where the first and
    +    // last base would be trimmed with a simple marker.
    +    // Most instances of the word "trimming" in this function is just moving first_base and last_base.
    +    let mut first_base = 0;
         // The last position is either the last_base parameter
         // or the last position in the string, whichever is less.
    -    let last_base_tmp = match last_base {
    -        // But if the position is not specified, then it is the seq length
    -        0 => {
    -            // zero based
    -            seq.seq.len()-1
    -        },
    -        _ => {
    -            min(seq.seq.len()-1, last_base)
    +    let mut last_base = seq.seq.len()-1;
    +
    +    // Make note of what is trimmed
    +    let mut description = String::new();
    +
    +    // First, run the adapter trimming, before any blunt end trimming
    +
    +    // First, detect if there are any adapters in the sequence
    +    // If there are, then trim the sequence at the adapter
    +    for adapter in adapters {
    +        let adapter_length = adapter.len();
    +        
    +        // If the adapter is longer than the sequence, skip it: it won't exist in the sequence as a whole adapter.
    +        if adapter_length >= seq.seq.len() {
    +            continue;
    +        }
    +        
    +        // Check if the adapter is at the beginning of the sequence
    +        if &seq.seq[0..adapter_length] == adapter {
    +            first_base = adapter_length;
    +            description.push_str(&format!(" trimmed_adapter_fwd={}", &adapter));
    +        }
    +        
    +        // Check if the revcom is at the end of the sequence
    +        let revcom = reverse_complement(&adapter);
    +        let end_slice: &str = &seq.seq[&seq.seq.len()-1 - adapter_length..].trim();
    +        if end_slice == revcom {
    +            last_base = seq.seq.len() - adapter_length;
    +            description.push_str(&format!(" trimmed_adapter_rev={}", &revcom));
    +        }
    +    }
    +
    +    // Next, run the blunt end trimming.
    +    // Take the maximum between the suggested left trim and the current left trim.
    +    // If the left trim is longer than the sequence length, then omit a warning and do not trim.
    +    first_base = max(first_base, suggested_first_base);
    +    if first_base >= seq.seq.len() {
    +        logmsg("Warning: the left trim is longer than the sequence length.  Skipping.");
    +        first_base = 0;
    +    }
    +
    +    // Take the minimum between the suggested right trim and the current right trim.
    +    // If the last base is less than 1, then omit a warning and do not trim.
    +    last_base = {
    +        if suggested_last_base == 0 {
    +            last_base
    +        } else {
    +            min(last_base, suggested_last_base)
             }
         };
    +    if last_base < 1 {
    +        logmsg("Warning: the right trim is longer than the sequence length.  Skipping.");
    +        last_base = seq.seq.len()-1;
    +    }
     
    -    let sequence = &seq.seq[first_base..last_base_tmp];
    -    let quality  = &seq.qual[first_base..last_base_tmp];
    +    description.push_str(&format!(" trimmed_left={} trimmed_right={}", first_base, last_base-1));
     
    -    let trimmed = format!("{}\n{}\n+\n{}", seq.id, sequence, quality);
    +    let sequence = &seq.seq[first_base..last_base];
    +    let quality  = &seq.qual[first_base..last_base];
    +
    +    let trimmed = format!("{}{}\n{}\n+\n{}", seq.id, description, sequence, quality);
         return trimmed;
     }
    -  
    +
    +// Taken from https://medium.com/bioinformatics-with-rust/how-to-read-a-fasta-file-9472b77589f7
    +/// Read a fasta file and return a HashMap of the sequences
    +fn read_fasta(file_path: &str) -> HashMap<String, String> {
    +    let mut data = HashMap::new();
    +    let file = File::open(file_path).expect("Invalid filepath");
    +    let reader = BufReader::new(file);
    +    
    +    let mut seq_id = String::new();
    +
    +    for line in reader.lines() {
    +        let line = line.unwrap();
    +        
    +        // Check if the line starts with '>' (indicating a sequence ID or header)
    +        if line.starts_with('>') {
    +            seq_id = line.trim_start_matches('>').to_string();
    +        } else {
    +            // If it's a DNA sequence line, insert or update the HashMap entry
    +            // If seq_id is not present, insert a new entry with an empty String
    +            // Then append the current line to the existing DNA sequence
    +            data.entry(seq_id.clone()).or_insert_with(String::new).push_str(&line);
    +        }
    +    }
    +    
    +    data
    +}
     
     
    \ No newline at end of file diff --git a/docs/src/fasten_validate/fasten_validate.rs.html b/docs/src/fasten_validate/fasten_validate.rs.html index 2938d8a0..92bcaa7b 100644 --- a/docs/src/fasten_validate/fasten_validate.rs.html +++ b/docs/src/fasten_validate/fasten_validate.rs.html @@ -1,4 +1,6 @@ -fasten_validate.rs - source
    1
    +fasten_validate.rs - source
    +    
    1
     2
     3
     4
    @@ -193,12 +195,12 @@
     //! Large-scale validation of PE reads
     //! with 4 CPUs and xargs
     //! ```bash
    -//! \ls *_1.fastq.gz | xargs -n 1 -P 4 bash -c '
    -//!   echo -n "." >&2 # progress bar
    +//! \ls *_1.fastq.gz | xargs -n 1 -P 4 bash -c '
    +//!   echo -n "." >&2 # progress bar
     //!   R1=$0
     //!   R2=${0/_1.fastq.gz/_2.fastq.gz}
     //!   zcat $R1 $R2 | fasten_shuffle | fasten_validate --paired-end
    -//! '
    +//! '
     //! ```
     //! 
     //! # Usage
    @@ -234,42 +236,42 @@
     use fasten::logmsg;
     
     fn main(){
    -    logmsg("NOTE: fasten_validate is deprecated starting in v0.6 in favor of fasten_inspect and fasten_repair");
    +    logmsg("NOTE: fasten_validate is deprecated starting in v0.6 in favor of fasten_inspect and fasten_repair");
         let mut opts = fasten_base_options();
         // Options specific to this script
    -    opts.optopt("","min-length","Minimum read length allowed","INT");
    -    opts.optopt("","min-quality","Minimum quality allowed","FLOAT");
    -    opts.optflag("","paired-end","The reads are interleaved paired-end");
    -    opts.optflag("","print-reads","Print the reads as they are being validated (useful for unix pipes)");
    +    opts.optopt("","min-length","Minimum read length allowed","INT");
    +    opts.optopt("","min-quality","Minimum quality allowed","FLOAT");
    +    opts.optflag("","paired-end","The reads are interleaved paired-end");
    +    opts.optflag("","print-reads","Print the reads as they are being validated (useful for unix pipes)");
     
    -    let matches = fasten_base_options_matches("Validates your reads and makes you feel good about yourself!", opts);
    +    let matches = fasten_base_options_matches("Validates your reads and makes you feel good about yourself!", opts);
     
    -    let my_file = File::open("/dev/stdin").expect("Could not open file");
    +    let my_file = File::open("/dev/stdin").expect("Could not open file");
         let my_buffer=BufReader::new(my_file);
     
         let lines_per_read={
    -        if matches.opt_present("paired-end") {
    +        if matches.opt_present("paired-end") {
                 8
             }else{
                 4
             }
         };
         let min_length :usize={
    -        if matches.opt_present("min-length") {
    -            matches.opt_str("min-length")
    -                .expect("ERROR parsing min-length")
    +        if matches.opt_present("min-length") {
    +            matches.opt_str("min-length")
    +                .expect("ERROR parsing min-length")
                     .parse()
    -                .expect("ERROR parsing min-length as INT")
    +                .expect("ERROR parsing min-length as INT")
             } else {
                 0
             }
         };
         let min_qual :f32={
    -        if matches.opt_present("min-quality") {
    -            matches.opt_str("min-quality")
    -                .expect("ERROR parsing min-quality")
    +        if matches.opt_present("min-quality") {
    +            matches.opt_str("min-quality")
    +                .expect("ERROR parsing min-quality")
                     .parse()
    -                .expect("ERROR parsing min-quality as FLOAT")
    +                .expect("ERROR parsing min-quality as FLOAT")
             } else {
                 0.0
             }
    @@ -278,51 +280,51 @@
     
         // save this option to avoid the overhead of calling
         // opt_present many times in a loop
    -    let should_print=matches.opt_present("print-reads");
    +    let should_print=matches.opt_present("print-reads");
     
         // If there is a match on these, then mark invalid.
         // In other words, we are looking for a pattern that
         // is NOT the target seq or qual
    -    let seq_regex = Regex::new(r"[^a-zA-Z]").expect("malformed seq regex");
    -    //let qual_regex= Regex::new(r"[^!-Za-z]").expect("malformed qual regex");
    -    let qual_regex= Regex::new(r"\s").expect("malformed qual regex");
    +    let seq_regex = Regex::new(r"[^a-zA-Z]").expect("malformed seq regex");
    +    //let qual_regex= Regex::new(r"[^!-Za-z]").expect("malformed qual regex");
    +    let qual_regex= Regex::new(r"\s").expect("malformed qual regex");
     
         // TODO have a print buffer, something like 4096 bytes
     
         let mut i = 0;
         for line in my_buffer.lines() {
    -        let line=line.expect("ERROR: did not get a line");
    +        let line=line.expect("ERROR: did not get a line");
             if should_print {
    -            println!("{}",line);
    +            println!("{}",line);
             }
     
             // TODO pattern match for each kind of line:
             // id, seq, +, qual
             match i%4{
                 0=>{
    -                if line.chars().nth(0).unwrap() != '@' {
    -                    panic!("ERROR: first character of the identifier is not @ in the line {}. Contents are:\n  {}",i,line); 
    +                if line.chars().nth(0).unwrap() != '@' {
    +                    panic!("ERROR: first character of the identifier is not @ in the line {}. Contents are:\n  {}",i,line); 
                     }
                 }
                 1=>{
                     if seq_regex.is_match(&line) {
    -                    panic!("ERROR: there are characters that are not in the alphabet in line {}. Contents are:\n  {}",i,line);
    +                    panic!("ERROR: there are characters that are not in the alphabet in line {}. Contents are:\n  {}",i,line);
                     }
                     if min_length > 0 && line.len() > min_length {
    -                    panic!("ERROR: sequence at line {} is less than the minimum sequence length",i);
    +                    panic!("ERROR: sequence at line {} is less than the minimum sequence length",i);
                     }
                 }
                 2=>{
    -                if line.chars().nth(0).unwrap() != '+' {
    -                    panic!("ERROR: first character of the qual identifier is not + in the line {}. Contents are:\n  {}",i,line); 
    +                if line.chars().nth(0).unwrap() != '+' {
    +                    panic!("ERROR: first character of the qual identifier is not + in the line {}. Contents are:\n  {}",i,line); 
                     }
                 }
                 3=>{
                     if qual_regex.is_match(&line) {
                         for cap in qual_regex.captures_iter(&line) {
    -                        eprintln!("Illegal qual character found: {}", &cap[0]);
    +                        eprintln!("Illegal qual character found: {}", &cap[0]);
                         }
    -                    panic!("ERROR: there are characters that are not qual characters in line {}. Contents are:\n  {}",i,line);
    +                    panic!("ERROR: there are characters that are not qual characters in line {}. Contents are:\n  {}",i,line);
                     }
                     // only calculate read quality if we are testing for it
                     if min_qual > 0.0 {
    @@ -332,22 +334,22 @@
                         }
                         let avg_qual :f32 = qual_total as f32 / line.len() as f32 - 33.0;
                         if avg_qual < min_qual {
    -                        panic!("ERROR: quality is less than min qual in line {}.\n  Avg qual is {}.\n  Min qual is {}\n  Contents are:\n  {}",i,avg_qual,min_qual,line);
    +                        panic!("ERROR: quality is less than min qual in line {}.\n  Avg qual is {}.\n  Min qual is {}\n  Contents are:\n  {}",i,avg_qual,min_qual,line);
                         }
                     }
                 }
                 _=>{
    -                panic!("INTERNAL ERROR");
    +                panic!("INTERNAL ERROR");
                 }
             }
             i += 1;
         }
         if i % lines_per_read > 0{
    -        panic!("ERROR: incomplete fastq entry. Num lines: {}",i);
    +        panic!("ERROR: incomplete fastq entry. Num lines: {}",i);
         }
     
    -    if matches.opt_present("verbose") {
    -        fasten::logmsg("These reads have been validated!");
    +    if matches.opt_present("verbose") {
    +        fasten::logmsg("These reads have been validated!");
         }
     }
     
    diff --git a/docs/static.files/main-48f368f3872407c8.js b/docs/static.files/main-48f368f3872407c8.js
    new file mode 100644
    index 00000000..987fae42
    --- /dev/null
    +++ b/docs/static.files/main-48f368f3872407c8.js
    @@ -0,0 +1,11 @@
    +"use strict";window.RUSTDOC_TOOLTIP_HOVER_MS=300;window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS=450;function resourcePath(basename,extension){return getVar("root-path")+basename+getVar("resource-suffix")+extension}function hideMain(){addClass(document.getElementById(MAIN_ID),"hidden")}function showMain(){removeClass(document.getElementById(MAIN_ID),"hidden")}function blurHandler(event,parentElem,hideCallback){if(!parentElem.contains(document.activeElement)&&!parentElem.contains(event.relatedTarget)){hideCallback()}}window.rootPath=getVar("root-path");window.currentCrate=getVar("current-crate");function setMobileTopbar(){const mobileTopbar=document.querySelector(".mobile-topbar");const locationTitle=document.querySelector(".sidebar h2.location");if(mobileTopbar){const mobileTitle=document.createElement("h2");mobileTitle.className="location";if(hasClass(document.querySelector(".rustdoc"),"crate")){mobileTitle.innerText=`Crate ${window.currentCrate}`}else if(locationTitle){mobileTitle.innerHTML=locationTitle.innerHTML}mobileTopbar.appendChild(mobileTitle)}}function getVirtualKey(ev){if("key"in ev&&typeof ev.key!=="undefined"){return ev.key}const c=ev.charCode||ev.keyCode;if(c===27){return"Escape"}return String.fromCharCode(c)}const MAIN_ID="main-content";const SETTINGS_BUTTON_ID="settings-menu";const ALTERNATIVE_DISPLAY_ID="alternative-display";const NOT_DISPLAYED_ID="not-displayed";const HELP_BUTTON_ID="help-button";function getSettingsButton(){return document.getElementById(SETTINGS_BUTTON_ID)}function getHelpButton(){return document.getElementById(HELP_BUTTON_ID)}function getNakedUrl(){return window.location.href.split("?")[0].split("#")[0]}function insertAfter(newNode,referenceNode){referenceNode.parentNode.insertBefore(newNode,referenceNode.nextSibling)}function getOrCreateSection(id,classes){let el=document.getElementById(id);if(!el){el=document.createElement("section");el.id=id;el.className=classes;insertAfter(el,document.getElementById(MAIN_ID))}return el}function getAlternativeDisplayElem(){return getOrCreateSection(ALTERNATIVE_DISPLAY_ID,"content hidden")}function getNotDisplayedElem(){return getOrCreateSection(NOT_DISPLAYED_ID,"hidden")}function switchDisplayedElement(elemToDisplay){const el=getAlternativeDisplayElem();if(el.children.length>0){getNotDisplayedElem().appendChild(el.firstElementChild)}if(elemToDisplay===null){addClass(el,"hidden");showMain();return}el.appendChild(elemToDisplay);hideMain();removeClass(el,"hidden")}function browserSupportsHistoryApi(){return window.history&&typeof window.history.pushState==="function"}function preLoadCss(cssUrl){const link=document.createElement("link");link.href=cssUrl;link.rel="preload";link.as="style";document.getElementsByTagName("head")[0].appendChild(link)}(function(){const isHelpPage=window.location.pathname.endsWith("/help.html");function loadScript(url){const script=document.createElement("script");script.src=url;document.head.append(script)}getSettingsButton().onclick=event=>{if(event.ctrlKey||event.altKey||event.metaKey){return}window.hideAllModals(false);addClass(getSettingsButton(),"rotate");event.preventDefault();loadScript(getVar("static-root-path")+getVar("settings-js"));setTimeout(()=>{const themes=getVar("themes").split(",");for(const theme of themes){if(theme!==""){preLoadCss(getVar("root-path")+theme+".css")}}},0)};window.searchState={loadingText:"Loading search results...",input:document.getElementsByClassName("search-input")[0],outputElement:()=>{let el=document.getElementById("search");if(!el){el=document.createElement("section");el.id="search";getNotDisplayedElem().appendChild(el)}return el},title:document.title,titleBeforeSearch:document.title,timeout:null,currentTab:0,focusedByTab:[null,null,null],clearInputTimeout:()=>{if(searchState.timeout!==null){clearTimeout(searchState.timeout);searchState.timeout=null}},isDisplayed:()=>searchState.outputElement().parentElement.id===ALTERNATIVE_DISPLAY_ID,focus:()=>{searchState.input.focus()},defocus:()=>{searchState.input.blur()},showResults:search=>{if(search===null||typeof search==="undefined"){search=searchState.outputElement()}switchDisplayedElement(search);searchState.mouseMovedAfterSearch=false;document.title=searchState.title},removeQueryParameters:()=>{document.title=searchState.titleBeforeSearch;if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.hash)}},hideResults:()=>{switchDisplayedElement(null);searchState.removeQueryParameters()},getQueryStringParams:()=>{const params={};window.location.search.substring(1).split("&").map(s=>{const pair=s.split("=").map(x=>x.replace(/\+/g," "));params[decodeURIComponent(pair[0])]=typeof pair[1]==="undefined"?null:decodeURIComponent(pair[1])});return params},setup:()=>{const search_input=searchState.input;if(!searchState.input){return}let searchLoaded=false;function loadSearch(){if(!searchLoaded){searchLoaded=true;loadScript(getVar("static-root-path")+getVar("search-js"));loadScript(resourcePath("search-index",".js"))}}search_input.addEventListener("focus",()=>{search_input.origPlaceholder=search_input.placeholder;search_input.placeholder="Type your search here.";loadSearch()});if(search_input.value!==""){loadSearch()}const params=searchState.getQueryStringParams();if(params.search!==undefined){searchState.setLoadingSearch();loadSearch()}},setLoadingSearch:()=>{const search=searchState.outputElement();search.innerHTML="

    "+searchState.loadingText+"

    ";searchState.showResults(search)},};const toggleAllDocsId="toggle-all-docs";let savedHash="";function handleHashes(ev){if(ev!==null&&searchState.isDisplayed()&&ev.newURL){switchDisplayedElement(null);const hash=ev.newURL.slice(ev.newURL.indexOf("#")+1);if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.search+"#"+hash)}const elem=document.getElementById(hash);if(elem){elem.scrollIntoView()}}const pageId=window.location.hash.replace(/^#/,"");if(savedHash!==pageId){savedHash=pageId;if(pageId!==""){expandSection(pageId)}}if(savedHash.startsWith("impl-")){const splitAt=savedHash.indexOf("/");if(splitAt!==-1){const implId=savedHash.slice(0,splitAt);const assocId=savedHash.slice(splitAt+1);const implElem=document.getElementById(implId);if(implElem&&implElem.parentElement.tagName==="SUMMARY"&&implElem.parentElement.parentElement.tagName==="DETAILS"){onEachLazy(implElem.parentElement.parentElement.querySelectorAll(`[id^="${assocId}"]`),item=>{const numbered=/([^-]+)-([0-9]+)/.exec(item.id);if(item.id===assocId||(numbered&&numbered[1]===assocId)){openParentDetails(item);item.scrollIntoView();setTimeout(()=>{window.location.replace("#"+item.id)},0)}})}}}}function onHashChange(ev){hideSidebar();handleHashes(ev)}function openParentDetails(elem){while(elem){if(elem.tagName==="DETAILS"){elem.open=true}elem=elem.parentNode}}function expandSection(id){openParentDetails(document.getElementById(id))}function handleEscape(ev){searchState.clearInputTimeout();searchState.hideResults();ev.preventDefault();searchState.defocus();window.hideAllModals(true)}function handleShortcut(ev){const disableShortcuts=getSettingValue("disable-shortcuts")==="true";if(ev.ctrlKey||ev.altKey||ev.metaKey||disableShortcuts){return}if(document.activeElement.tagName==="INPUT"&&document.activeElement.type!=="checkbox"&&document.activeElement.type!=="radio"){switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break}}else{switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break;case"s":case"S":ev.preventDefault();searchState.focus();break;case"+":ev.preventDefault();expandAllDocs();break;case"-":ev.preventDefault();collapseAllDocs();break;case"?":showHelp();break;default:break}}}document.addEventListener("keypress",handleShortcut);document.addEventListener("keydown",handleShortcut);function addSidebarItems(){if(!window.SIDEBAR_ITEMS){return}const sidebar=document.getElementsByClassName("sidebar-elems")[0];function block(shortty,id,longty){const filtered=window.SIDEBAR_ITEMS[shortty];if(!filtered){return}const modpath=hasClass(document.querySelector(".rustdoc"),"mod")?"../":"";const h3=document.createElement("h3");h3.innerHTML=`${longty}`;const ul=document.createElement("ul");ul.className="block "+shortty;for(const name of filtered){let path;if(shortty==="mod"){path=`${modpath}${name}/index.html`}else{path=`${modpath}${shortty}.${name}.html`}let current_page=document.location.href.toString();if(current_page.endsWith("/")){current_page+="index.html"}const link=document.createElement("a");link.href=path;if(path===current_page){link.className="current"}link.textContent=name;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebar.appendChild(h3);sidebar.appendChild(ul)}if(sidebar){block("primitive","primitives","Primitive Types");block("mod","modules","Modules");block("macro","macros","Macros");block("struct","structs","Structs");block("enum","enums","Enums");block("constant","constants","Constants");block("static","static","Statics");block("trait","traits","Traits");block("fn","functions","Functions");block("type","types","Type Aliases");block("union","unions","Unions");block("foreigntype","foreign-types","Foreign Types");block("keyword","keywords","Keywords");block("opaque","opaque-types","Opaque Types");block("attr","attributes","Attribute Macros");block("derive","derives","Derive Macros");block("traitalias","trait-aliases","Trait Aliases")}}window.register_implementors=imp=>{const implementors=document.getElementById("implementors-list");const synthetic_implementors=document.getElementById("synthetic-implementors-list");const inlined_types=new Set();const TEXT_IDX=0;const SYNTHETIC_IDX=1;const TYPES_IDX=2;if(synthetic_implementors){onEachLazy(synthetic_implementors.getElementsByClassName("impl"),el=>{const aliases=el.getAttribute("data-aliases");if(!aliases){return}aliases.split(",").forEach(alias=>{inlined_types.add(alias)})})}let currentNbImpls=implementors.getElementsByClassName("impl").length;const traitName=document.querySelector(".main-heading h1 > .trait").textContent;const baseIdName="impl-"+traitName+"-";const libs=Object.getOwnPropertyNames(imp);const script=document.querySelector("script[data-ignore-extern-crates]");const ignoreExternCrates=new Set((script?script.getAttribute("data-ignore-extern-crates"):"").split(","));for(const lib of libs){if(lib===window.currentCrate||ignoreExternCrates.has(lib)){continue}const structs=imp[lib];struct_loop:for(const struct of structs){const list=struct[SYNTHETIC_IDX]?synthetic_implementors:implementors;if(struct[SYNTHETIC_IDX]){for(const struct_type of struct[TYPES_IDX]){if(inlined_types.has(struct_type)){continue struct_loop}inlined_types.add(struct_type)}}const code=document.createElement("h3");code.innerHTML=struct[TEXT_IDX];addClass(code,"code-header");onEachLazy(code.getElementsByTagName("a"),elem=>{const href=elem.getAttribute("href");if(href&&!href.startsWith("#")&&!/^(?:[a-z+]+:)?\/\//.test(href)){elem.setAttribute("href",window.rootPath+href)}});const currentId=baseIdName+currentNbImpls;const anchor=document.createElement("a");anchor.href="#"+currentId;addClass(anchor,"anchor");const display=document.createElement("div");display.id=currentId;addClass(display,"impl");display.appendChild(anchor);display.appendChild(code);list.appendChild(display);currentNbImpls+=1}}};if(window.pending_implementors){window.register_implementors(window.pending_implementors)}window.register_type_impls=imp=>{if(!imp||!imp[window.currentCrate]){return}window.pending_type_impls=null;const idMap=new Map();let implementations=document.getElementById("implementations-list");let trait_implementations=document.getElementById("trait-implementations-list");let trait_implementations_header=document.getElementById("trait-implementations");const script=document.querySelector("script[data-self-path]");const selfPath=script?script.getAttribute("data-self-path"):null;const mainContent=document.querySelector("#main-content");const sidebarSection=document.querySelector(".sidebar section");let methods=document.querySelector(".sidebar .block.method");let associatedTypes=document.querySelector(".sidebar .block.associatedtype");let associatedConstants=document.querySelector(".sidebar .block.associatedconstant");let sidebarTraitList=document.querySelector(".sidebar .block.trait-implementation");for(const impList of imp[window.currentCrate]){const types=impList.slice(2);const text=impList[0];const isTrait=impList[1]!==0;const traitName=impList[1];if(types.indexOf(selfPath)===-1){continue}let outputList=isTrait?trait_implementations:implementations;if(outputList===null){const outputListName=isTrait?"Trait Implementations":"Implementations";const outputListId=isTrait?"trait-implementations-list":"implementations-list";const outputListHeaderId=isTrait?"trait-implementations":"implementations";const outputListHeader=document.createElement("h2");outputListHeader.id=outputListHeaderId;outputListHeader.innerText=outputListName;outputList=document.createElement("div");outputList.id=outputListId;if(isTrait){const link=document.createElement("a");link.href=`#${outputListHeaderId}`;link.innerText="Trait Implementations";const h=document.createElement("h3");h.appendChild(link);trait_implementations=outputList;trait_implementations_header=outputListHeader;sidebarSection.appendChild(h);sidebarTraitList=document.createElement("ul");sidebarTraitList.className="block trait-implementation";sidebarSection.appendChild(sidebarTraitList);mainContent.appendChild(outputListHeader);mainContent.appendChild(outputList)}else{implementations=outputList;if(trait_implementations){mainContent.insertBefore(outputListHeader,trait_implementations_header);mainContent.insertBefore(outputList,trait_implementations_header)}else{const mainContent=document.querySelector("#main-content");mainContent.appendChild(outputListHeader);mainContent.appendChild(outputList)}}}const template=document.createElement("template");template.innerHTML=text;onEachLazy(template.content.querySelectorAll("a"),elem=>{const href=elem.getAttribute("href");if(href&&!href.startsWith("#")&&!/^(?:[a-z+]+:)?\/\//.test(href)){elem.setAttribute("href",window.rootPath+href)}});onEachLazy(template.content.querySelectorAll("[id]"),el=>{let i=0;if(idMap.has(el.id)){i=idMap.get(el.id)}else if(document.getElementById(el.id)){i=1;while(document.getElementById(`${el.id}-${2 * i}`)){i=2*i}while(document.getElementById(`${el.id}-${i}`)){i+=1}}if(i!==0){const oldHref=`#${el.id}`;const newHref=`#${el.id}-${i}`;el.id=`${el.id}-${i}`;onEachLazy(template.content.querySelectorAll("a[href]"),link=>{if(link.getAttribute("href")===oldHref){link.href=newHref}})}idMap.set(el.id,i+1)});const templateAssocItems=template.content.querySelectorAll("section.tymethod, "+"section.method, section.associatedtype, section.associatedconstant");if(isTrait){const li=document.createElement("li");const a=document.createElement("a");a.href=`#${template.content.querySelector(".impl").id}`;a.textContent=traitName;li.appendChild(a);sidebarTraitList.append(li)}else{onEachLazy(templateAssocItems,item=>{let block=hasClass(item,"associatedtype")?associatedTypes:(hasClass(item,"associatedconstant")?associatedConstants:(methods));if(!block){const blockTitle=hasClass(item,"associatedtype")?"Associated Types":(hasClass(item,"associatedconstant")?"Associated Constants":("Methods"));const blockClass=hasClass(item,"associatedtype")?"associatedtype":(hasClass(item,"associatedconstant")?"associatedconstant":("method"));const blockHeader=document.createElement("h3");const blockLink=document.createElement("a");blockLink.href="#implementations";blockLink.innerText=blockTitle;blockHeader.appendChild(blockLink);block=document.createElement("ul");block.className=`block ${blockClass}`;const insertionReference=methods||sidebarTraitList;if(insertionReference){const insertionReferenceH=insertionReference.previousElementSibling;sidebarSection.insertBefore(blockHeader,insertionReferenceH);sidebarSection.insertBefore(block,insertionReferenceH)}else{sidebarSection.appendChild(blockHeader);sidebarSection.appendChild(block)}if(hasClass(item,"associatedtype")){associatedTypes=block}else if(hasClass(item,"associatedconstant")){associatedConstants=block}else{methods=block}}const li=document.createElement("li");const a=document.createElement("a");a.innerText=item.id.split("-")[0].split(".")[1];a.href=`#${item.id}`;li.appendChild(a);block.appendChild(li)})}outputList.appendChild(template.content)}for(const list of[methods,associatedTypes,associatedConstants,sidebarTraitList]){if(!list){continue}const newChildren=Array.prototype.slice.call(list.children);newChildren.sort((a,b)=>{const aI=a.innerText;const bI=b.innerText;return aIbI?1:0});list.replaceChildren(...newChildren)}};if(window.pending_type_impls){window.register_type_impls(window.pending_type_impls)}function addSidebarCrates(){if(!window.ALL_CRATES){return}const sidebarElems=document.getElementsByClassName("sidebar-elems")[0];if(!sidebarElems){return}const h3=document.createElement("h3");h3.innerHTML="Crates";const ul=document.createElement("ul");ul.className="block crate";for(const crate of window.ALL_CRATES){const link=document.createElement("a");link.href=window.rootPath+crate+"/index.html";link.textContent=crate;const li=document.createElement("li");if(window.rootPath!=="./"&&crate===window.currentCrate){li.className="current"}li.appendChild(link);ul.appendChild(li)}sidebarElems.appendChild(h3);sidebarElems.appendChild(ul)}function expandAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);removeClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hasClass(e,"type-contents-toggle")&&!hasClass(e,"more-examples-toggle")){e.open=true}});innerToggle.title="collapse all docs";innerToggle.children[0].innerText="\u2212"}function collapseAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);addClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(e.parentNode.id!=="implementations-list"||(!hasClass(e,"implementors-toggle")&&!hasClass(e,"type-contents-toggle"))){e.open=false}});innerToggle.title="expand all docs";innerToggle.children[0].innerText="+"}function toggleAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);if(!innerToggle){return}if(hasClass(innerToggle,"will-expand")){expandAllDocs()}else{collapseAllDocs()}}(function(){const toggles=document.getElementById(toggleAllDocsId);if(toggles){toggles.onclick=toggleAllDocs}const hideMethodDocs=getSettingValue("auto-hide-method-docs")==="true";const hideImplementations=getSettingValue("auto-hide-trait-implementations")==="true";const hideLargeItemContents=getSettingValue("auto-hide-large-items")!=="false";function setImplementorsTogglesOpen(id,open){const list=document.getElementById(id);if(list!==null){onEachLazy(list.getElementsByClassName("implementors-toggle"),e=>{e.open=open})}}if(hideImplementations){setImplementorsTogglesOpen("trait-implementations-list",false);setImplementorsTogglesOpen("blanket-implementations-list",false)}onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hideLargeItemContents&&hasClass(e,"type-contents-toggle")){e.open=true}if(hideMethodDocs&&hasClass(e,"method-toggle")){e.open=false}})}());window.rustdoc_add_line_numbers_to_examples=()=>{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");if(line_numbers.length>0){return}const count=x.textContent.split("\n").length;const elems=[];for(let i=0;i{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");for(const node of line_numbers){parent.removeChild(node)}})};if(getSettingValue("line-numbers")==="true"){window.rustdoc_add_line_numbers_to_examples()}function showSidebar(){window.hideAllModals(false);const sidebar=document.getElementsByClassName("sidebar")[0];addClass(sidebar,"shown")}function hideSidebar(){const sidebar=document.getElementsByClassName("sidebar")[0];removeClass(sidebar,"shown")}window.addEventListener("resize",()=>{if(window.CURRENT_TOOLTIP_ELEMENT){const base=window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE;const force_visible=base.TOOLTIP_FORCE_VISIBLE;hideTooltip(false);if(force_visible){showTooltip(base);base.TOOLTIP_FORCE_VISIBLE=true}}});const mainElem=document.getElementById(MAIN_ID);if(mainElem){mainElem.addEventListener("click",hideSidebar)}onEachLazy(document.querySelectorAll("a[href^='#']"),el=>{el.addEventListener("click",()=>{expandSection(el.hash.slice(1));hideSidebar()})});onEachLazy(document.querySelectorAll(".toggle > summary:not(.hideme)"),el=>{el.addEventListener("click",e=>{if(e.target.tagName!=="SUMMARY"&&e.target.tagName!=="A"){e.preventDefault()}})});function showTooltip(e){const notable_ty=e.getAttribute("data-notable-ty");if(!window.NOTABLE_TRAITS&¬able_ty){const data=document.getElementById("notable-traits-data");if(data){window.NOTABLE_TRAITS=JSON.parse(data.innerText)}else{throw new Error("showTooltip() called with notable without any notable traits!")}}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE===e){clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);return}window.hideAllModals(false);const wrapper=document.createElement("div");if(notable_ty){wrapper.innerHTML="
    "+window.NOTABLE_TRAITS[notable_ty]+"
    "}else{if(e.getAttribute("title")!==null){e.setAttribute("data-title",e.getAttribute("title"));e.removeAttribute("title")}if(e.getAttribute("data-title")!==null){const titleContent=document.createElement("div");titleContent.className="content";titleContent.appendChild(document.createTextNode(e.getAttribute("data-title")));wrapper.appendChild(titleContent)}}wrapper.className="tooltip popover";const focusCatcher=document.createElement("div");focusCatcher.setAttribute("tabindex","0");focusCatcher.onfocus=hideTooltip;wrapper.appendChild(focusCatcher);const pos=e.getBoundingClientRect();wrapper.style.top=(pos.top+window.scrollY+pos.height)+"px";wrapper.style.left=0;wrapper.style.right="auto";wrapper.style.visibility="hidden";const body=document.getElementsByTagName("body")[0];body.appendChild(wrapper);const wrapperPos=wrapper.getBoundingClientRect();const finalPos=pos.left+window.scrollX-wrapperPos.width+24;if(finalPos>0){wrapper.style.left=finalPos+"px"}else{wrapper.style.setProperty("--popover-arrow-offset",(wrapperPos.right-pos.right+4)+"px")}wrapper.style.visibility="";window.CURRENT_TOOLTIP_ELEMENT=wrapper;window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE=e;clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);wrapper.onpointerenter=ev=>{if(ev.pointerType!=="mouse"){return}clearTooltipHoverTimeout(e)};wrapper.onpointerleave=ev=>{if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&!e.contains(ev.relatedTarget)){setTooltipHoverTimeout(e,false);addClass(wrapper,"fade-out")}}}function setTooltipHoverTimeout(element,show){clearTooltipHoverTimeout(element);if(!show&&!window.CURRENT_TOOLTIP_ELEMENT){return}if(show&&window.CURRENT_TOOLTIP_ELEMENT){return}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE!==element){return}element.TOOLTIP_HOVER_TIMEOUT=setTimeout(()=>{if(show){showTooltip(element)}else if(!element.TOOLTIP_FORCE_VISIBLE){hideTooltip(false)}},show?window.RUSTDOC_TOOLTIP_HOVER_MS:window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS)}function clearTooltipHoverTimeout(element){if(element.TOOLTIP_HOVER_TIMEOUT!==undefined){removeClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out");clearTimeout(element.TOOLTIP_HOVER_TIMEOUT);delete element.TOOLTIP_HOVER_TIMEOUT}}function tooltipBlurHandler(event){if(window.CURRENT_TOOLTIP_ELEMENT&&!window.CURRENT_TOOLTIP_ELEMENT.contains(document.activeElement)&&!window.CURRENT_TOOLTIP_ELEMENT.contains(event.relatedTarget)&&!window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.contains(document.activeElement)&&!window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.contains(event.relatedTarget)){setTimeout(()=>hideTooltip(false),0)}}function hideTooltip(focus){if(window.CURRENT_TOOLTIP_ELEMENT){if(window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE){if(focus){window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.focus()}window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE=false}const body=document.getElementsByTagName("body")[0];body.removeChild(window.CURRENT_TOOLTIP_ELEMENT);clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);window.CURRENT_TOOLTIP_ELEMENT=null}}onEachLazy(document.getElementsByClassName("tooltip"),e=>{e.onclick=()=>{e.TOOLTIP_FORCE_VISIBLE=e.TOOLTIP_FORCE_VISIBLE?false:true;if(window.CURRENT_TOOLTIP_ELEMENT&&!e.TOOLTIP_FORCE_VISIBLE){hideTooltip(true)}else{showTooltip(e);window.CURRENT_TOOLTIP_ELEMENT.setAttribute("tabindex","0");window.CURRENT_TOOLTIP_ELEMENT.focus();window.CURRENT_TOOLTIP_ELEMENT.onblur=tooltipBlurHandler}return false};e.onpointerenter=ev=>{if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(e,true)};e.onpointermove=ev=>{if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(e,true)};e.onpointerleave=ev=>{if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&window.CURRENT_TOOLTIP_ELEMENT&&!window.CURRENT_TOOLTIP_ELEMENT.contains(ev.relatedTarget)){setTooltipHoverTimeout(e,false);addClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out")}}});const sidebar_menu_toggle=document.getElementsByClassName("sidebar-menu-toggle")[0];if(sidebar_menu_toggle){sidebar_menu_toggle.addEventListener("click",()=>{const sidebar=document.getElementsByClassName("sidebar")[0];if(!hasClass(sidebar,"shown")){showSidebar()}else{hideSidebar()}})}function helpBlurHandler(event){blurHandler(event,getHelpButton(),window.hidePopoverMenus)}function buildHelpMenu(){const book_info=document.createElement("span");const channel=getVar("channel");book_info.className="top";book_info.innerHTML=`You can find more information in \ +the rustdoc book.`;const shortcuts=[["?","Show this help dialog"],["S","Focus the search field"],["↑","Move up in search results"],["↓","Move down in search results"],["← / →","Switch result tab (when results focused)"],["⏎","Go to active search result"],["+","Expand all sections"],["-","Collapse all sections"],].map(x=>"
    "+x[0].split(" ").map((y,index)=>((index&1)===0?""+y+"":" "+y+" ")).join("")+"
    "+x[1]+"
    ").join("");const div_shortcuts=document.createElement("div");addClass(div_shortcuts,"shortcuts");div_shortcuts.innerHTML="

    Keyboard Shortcuts

    "+shortcuts+"
    ";const infos=[`For a full list of all search features, take a look here.`,"Prefix searches with a type followed by a colon (e.g., fn:) to \ + restrict the search to a given item kind.","Accepted kinds are: fn, mod, struct, \ + enum, trait, type, macro, \ + and const.","Search functions by type signature (e.g., vec -> usize or \ + -> vec or String, enum:Cow -> bool)","You can look for items with an exact name by putting double quotes around \ + your request: \"string\"","Look for functions that accept or return \ + slices and \ + arrays by writing \ + square brackets (e.g., -> [u8] or [] -> Option)","Look for items inside another one by searching for a path: vec::Vec",].map(x=>"

    "+x+"

    ").join("");const div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="

    Search Tricks

    "+infos;const rustdoc_version=document.createElement("span");rustdoc_version.className="bottom";const rustdoc_version_code=document.createElement("code");rustdoc_version_code.innerText="rustdoc "+getVar("rustdoc-version");rustdoc_version.appendChild(rustdoc_version_code);const container=document.createElement("div");if(!isHelpPage){container.className="popover"}container.id="help";container.style.display="none";const side_by_side=document.createElement("div");side_by_side.className="side-by-side";side_by_side.appendChild(div_shortcuts);side_by_side.appendChild(div_infos);container.appendChild(book_info);container.appendChild(side_by_side);container.appendChild(rustdoc_version);if(isHelpPage){const help_section=document.createElement("section");help_section.appendChild(container);document.getElementById("main-content").appendChild(help_section);container.style.display="block"}else{const help_button=getHelpButton();help_button.appendChild(container);container.onblur=helpBlurHandler;help_button.onblur=helpBlurHandler;help_button.children[0].onblur=helpBlurHandler}return container}window.hideAllModals=switchFocus=>{hideSidebar();window.hidePopoverMenus();hideTooltip(switchFocus)};window.hidePopoverMenus=()=>{onEachLazy(document.querySelectorAll(".search-form .popover"),elem=>{elem.style.display="none"})};function getHelpMenu(buildNeeded){let menu=getHelpButton().querySelector(".popover");if(!menu&&buildNeeded){menu=buildHelpMenu()}return menu}function showHelp(){getHelpButton().querySelector("a").focus();const menu=getHelpMenu(true);if(menu.style.display==="none"){window.hideAllModals();menu.style.display=""}}if(isHelpPage){showHelp();document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault()})}else{document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault();const menu=getHelpMenu(true);const shouldShowHelp=menu.style.display==="none";if(shouldShowHelp){showHelp()}else{window.hidePopoverMenus()}})}setMobileTopbar();addSidebarItems();addSidebarCrates();onHashChange(null);window.addEventListener("hashchange",onHashChange);searchState.setup()}());(function(){const SIDEBAR_MIN=100;const SIDEBAR_MAX=500;const RUSTDOC_MOBILE_BREAKPOINT=700;const BODY_MIN=400;const SIDEBAR_VANISH_THRESHOLD=SIDEBAR_MIN/2;const sidebarButton=document.getElementById("sidebar-button");if(sidebarButton){sidebarButton.addEventListener("click",e=>{removeClass(document.documentElement,"hide-sidebar");updateLocalStorage("hide-sidebar","false");if(document.querySelector(".rustdoc.src")){window.rustdocToggleSrcSidebar()}e.preventDefault()})}let currentPointerId=null;let desiredSidebarSize=null;let pendingSidebarResizingFrame=false;const resizer=document.querySelector(".sidebar-resizer");const sidebar=document.querySelector(".sidebar");if(!resizer||!sidebar){return}const isSrcPage=hasClass(document.body,"src");function hideSidebar(){if(isSrcPage){window.rustdocCloseSourceSidebar();updateLocalStorage("src-sidebar-width",null);document.documentElement.style.removeProperty("--src-sidebar-width");sidebar.style.removeProperty("--src-sidebar-width");resizer.style.removeProperty("--src-sidebar-width")}else{addClass(document.documentElement,"hide-sidebar");updateLocalStorage("hide-sidebar","true");updateLocalStorage("desktop-sidebar-width",null);document.documentElement.style.removeProperty("--desktop-sidebar-width");sidebar.style.removeProperty("--desktop-sidebar-width");resizer.style.removeProperty("--desktop-sidebar-width")}}function showSidebar(){if(isSrcPage){window.rustdocShowSourceSidebar()}else{removeClass(document.documentElement,"hide-sidebar");updateLocalStorage("hide-sidebar","false")}}function changeSidebarSize(size){if(isSrcPage){updateLocalStorage("src-sidebar-width",size);sidebar.style.setProperty("--src-sidebar-width",size+"px");resizer.style.setProperty("--src-sidebar-width",size+"px")}else{updateLocalStorage("desktop-sidebar-width",size);sidebar.style.setProperty("--desktop-sidebar-width",size+"px");resizer.style.setProperty("--desktop-sidebar-width",size+"px")}}function isSidebarHidden(){return isSrcPage?!hasClass(document.documentElement,"src-sidebar-expanded"):hasClass(document.documentElement,"hide-sidebar")}function resize(e){if(currentPointerId===null||currentPointerId!==e.pointerId){return}e.preventDefault();const pos=e.clientX-3;if(pos=SIDEBAR_MIN){if(isSidebarHidden()){showSidebar()}const constrainedPos=Math.min(pos,window.innerWidth-BODY_MIN,SIDEBAR_MAX);changeSidebarSize(constrainedPos);desiredSidebarSize=constrainedPos;if(pendingSidebarResizingFrame!==false){clearTimeout(pendingSidebarResizingFrame)}pendingSidebarResizingFrame=setTimeout(()=>{if(currentPointerId===null||pendingSidebarResizingFrame===false){return}pendingSidebarResizingFrame=false;document.documentElement.style.setProperty("--resizing-sidebar-width",desiredSidebarSize+"px")},100)}}window.addEventListener("resize",()=>{if(window.innerWidth=(window.innerWidth-BODY_MIN)){changeSidebarSize(window.innerWidth-BODY_MIN)}else if(desiredSidebarSize!==null&&desiredSidebarSize>SIDEBAR_MIN){changeSidebarSize(desiredSidebarSize)}});function stopResize(e){if(currentPointerId===null){return}if(e){e.preventDefault()}desiredSidebarSize=sidebar.getBoundingClientRect().width;removeClass(resizer,"active");window.removeEventListener("pointermove",resize,false);window.removeEventListener("pointerup",stopResize,false);removeClass(document.documentElement,"sidebar-resizing");document.documentElement.style.removeProperty("--resizing-sidebar-width");if(resizer.releasePointerCapture){resizer.releasePointerCapture(currentPointerId);currentPointerId=null}}function initResize(e){if(currentPointerId!==null||e.altKey||e.ctrlKey||e.metaKey||e.button!==0){return}if(resizer.setPointerCapture){resizer.setPointerCapture(e.pointerId);if(!resizer.hasPointerCapture(e.pointerId)){resizer.releasePointerCapture(e.pointerId);return}currentPointerId=e.pointerId}window.hideAllModals(false);e.preventDefault();window.addEventListener("pointermove",resize,false);window.addEventListener("pointercancel",stopResize,false);window.addEventListener("pointerup",stopResize,false);addClass(resizer,"active");addClass(document.documentElement,"sidebar-resizing");const pos=e.clientX-sidebar.offsetLeft-3;document.documentElement.style.setProperty("--resizing-sidebar-width",pos+"px");desiredSidebarSize=null}resizer.addEventListener("pointerdown",initResize,false)}());(function(){let reset_button_timeout=null;const but=document.getElementById("copy-path");if(!but){return}but.onclick=()=>{const parent=but.parentElement;const path=[];onEach(parent.childNodes,child=>{if(child.tagName==="A"){path.push(child.textContent)}});const el=document.createElement("textarea");el.value=path.join("::");el.setAttribute("readonly","");el.style.position="absolute";el.style.left="-9999px";document.body.appendChild(el);el.select();document.execCommand("copy");document.body.removeChild(el);but.children[0].style.display="none";let tmp;if(but.childNodes.length<2){tmp=document.createTextNode("✓");but.appendChild(tmp)}else{onEachLazy(but.childNodes,e=>{if(e.nodeType===Node.TEXT_NODE){tmp=e;return true}});tmp.textContent="✓"}if(reset_button_timeout!==null){window.clearTimeout(reset_button_timeout)}function reset_button(){tmp.textContent="";reset_button_timeout=null;but.children[0].style.display=""}reset_button_timeout=window.setTimeout(reset_button,1000)}}()) \ No newline at end of file diff --git a/docs/static.files/noscript-04d5337699b92874.css b/docs/static.files/noscript-04d5337699b92874.css new file mode 100644 index 00000000..fbd55f57 --- /dev/null +++ b/docs/static.files/noscript-04d5337699b92874.css @@ -0,0 +1 @@ + #main-content .attributes{margin-left:0 !important;}#copy-path,#sidebar-button,.sidebar-resizer{display:none !important;}nav.sub{display:none;}.src .sidebar{display:none;}.notable-traits{display:none;}:root{--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#f5f5f5;--sidebar-background-color-hover:#e0e0e0;--code-block-background-color:#f5f5f5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--mobile-sidebar-menu-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#fff;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--src-sidebar-background-selected:#fff;--src-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#f5f5f5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);--sidebar-resizer-hover:hsl(207,90%,66%);--sidebar-resizer-active:hsl(207,90%,54%);}@media (prefers-color-scheme:dark){:root{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--mobile-sidebar-menu-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--src-sidebar-background-selected:#333;--src-sidebar-background-hover:#444;--table-alt-row-background-color:#2a2a2a;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);--sidebar-resizer-hover:hsl(207,30%,54%);--sidebar-resizer-active:hsl(207,90%,54%);}} \ No newline at end of file diff --git a/docs/static.files/rustdoc-5bc39a1768837dd0.css b/docs/static.files/rustdoc-5bc39a1768837dd0.css new file mode 100644 index 00000000..175164ef --- /dev/null +++ b/docs/static.files/rustdoc-5bc39a1768837dd0.css @@ -0,0 +1,24 @@ + :root{--nav-sub-mobile-padding:8px;--search-typename-width:6.75rem;--desktop-sidebar-width:200px;--src-sidebar-width:300px;--desktop-sidebar-z-index:100;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:400;src:local('Fira Sans'),url("FiraSans-Regular-018c141bf0843ffd.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:500;src:local('Fira Sans Medium'),url("FiraSans-Medium-8f9a781e4970d388.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:400;src:local('Source Serif 4'),url("SourceSerif4-Regular-46f98efaafac5295.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:italic;font-weight:400;src:local('Source Serif 4 Italic'),url("SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:700;src:local('Source Serif 4 Bold'),url("SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:400;src:url("SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:italic;font-weight:400;src:url("SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:600;src:url("SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'NanumBarunGothic';src:url("NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2") format("woff2");font-display:swap;unicode-range:U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF;}*{box-sizing:border-box;}body{font:1rem/1.5 "Source Serif 4",NanumBarunGothic,serif;margin:0;position:relative;overflow-wrap:break-word;overflow-wrap:anywhere;font-feature-settings:"kern","liga";background-color:var(--main-background-color);color:var(--main-color);}h1{font-size:1.5rem;}h2{font-size:1.375rem;}h3{font-size:1.25rem;}h1,h2,h3,h4,h5,h6{font-weight:500;}h1,h2,h3,h4{margin:25px 0 15px 0;padding-bottom:6px;}.docblock h3,.docblock h4,h5,h6{margin:15px 0 5px 0;}.docblock>h2:first-child,.docblock>h3:first-child,.docblock>h4:first-child,.docblock>h5:first-child,.docblock>h6:first-child{margin-top:0;}.main-heading h1{margin:0;padding:0;flex-grow:1;overflow-wrap:break-word;overflow-wrap:anywhere;}.main-heading{display:flex;flex-wrap:wrap;padding-bottom:6px;margin-bottom:15px;}.content h2,.top-doc .docblock>h3,.top-doc .docblock>h4{border-bottom:1px solid var(--headings-border-bottom-color);}h1,h2{line-height:1.25;padding-top:3px;padding-bottom:9px;}h3.code-header{font-size:1.125rem;}h4.code-header{font-size:1rem;}.code-header{font-weight:600;margin:0;padding:0;white-space:pre-wrap;}#crate-search,h1,h2,h3,h4,h5,h6,.sidebar,.mobile-topbar,.search-input,.search-results .result-name,.item-name>a,.out-of-band,span.since,a.src,#help-button>a,summary.hideme,.scraped-example-list,ul.all-items{font-family:"Fira Sans",Arial,NanumBarunGothic,sans-serif;}#toggle-all-docs,a.anchor,.section-header a,#src-sidebar a,.rust a,.sidebar h2 a,.sidebar h3 a,.mobile-topbar h2 a,h1 a,.search-results a,.stab,.result-name i{color:var(--main-color);}span.enum,a.enum,span.struct,a.struct,span.union,a.union,span.primitive,a.primitive,span.type,a.type,span.foreigntype,a.foreigntype{color:var(--type-link-color);}span.trait,a.trait,span.traitalias,a.traitalias{color:var(--trait-link-color);}span.associatedtype,a.associatedtype,span.constant,a.constant,span.static,a.static{color:var(--assoc-item-link-color);}span.fn,a.fn,span.method,a.method,span.tymethod,a.tymethod{color:var(--function-link-color);}span.attr,a.attr,span.derive,a.derive,span.macro,a.macro{color:var(--macro-link-color);}span.mod,a.mod{color:var(--mod-link-color);}span.keyword,a.keyword{color:var(--keyword-link-color);}a{color:var(--link-color);text-decoration:none;}ol,ul{padding-left:24px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:.625em;}p,.docblock>.warning{margin:0 0 .75em 0;}p:last-child,.docblock>.warning:last-child{margin:0;}button{padding:1px 6px;cursor:pointer;}button#toggle-all-docs{padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.rustdoc{display:flex;flex-direction:row;flex-wrap:nowrap;}main{position:relative;flex-grow:1;padding:10px 15px 40px 45px;min-width:0;}.src main{padding:15px;}.width-limiter{max-width:960px;margin-right:auto;}details:not(.toggle) summary{margin-bottom:.6em;}code,pre,a.test-arrow,.code-header{font-family:"Source Code Pro",monospace;}.docblock code,.docblock-short code{border-radius:3px;padding:0 0.125em;}.docblock pre code,.docblock-short pre code{padding:0;}pre{padding:14px;line-height:1.5;}pre.item-decl{overflow-x:auto;}.item-decl .type-contents-toggle{contain:initial;}.src .content pre{padding:20px;}.rustdoc.src .example-wrap pre.src-line-numbers{padding:20px 0 20px 4px;}img{max-width:100%;}.logo-container{line-height:0;display:block;}.rust-logo{filter:var(--rust-logo-filter);}.sidebar{font-size:0.875rem;flex:0 0 var(--desktop-sidebar-width);width:var(--desktop-sidebar-width);overflow-y:scroll;overscroll-behavior:contain;position:sticky;height:100vh;top:0;left:0;z-index:var(--desktop-sidebar-z-index);}.rustdoc.src .sidebar{flex-basis:50px;width:50px;border-right:1px solid;overflow-x:hidden;overflow-y:hidden;}.hide-sidebar .sidebar,.hide-sidebar .sidebar-resizer{display:none;}.sidebar-resizer{touch-action:none;width:9px;cursor:col-resize;z-index:calc(var(--desktop-sidebar-z-index) + 1);position:fixed;height:100%;left:calc(var(--desktop-sidebar-width) + 1px);}.rustdoc.src .sidebar-resizer{left:49px;}.src-sidebar-expanded .src .sidebar-resizer{left:var(--src-sidebar-width);}.sidebar-resizing{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;}.sidebar-resizing*{cursor:col-resize !important;}.sidebar-resizing .sidebar{position:fixed;}.sidebar-resizing>body{padding-left:var(--resizing-sidebar-width);}.sidebar-resizer:hover,.sidebar-resizer:active,.sidebar-resizer:focus,.sidebar-resizer.active{width:10px;margin:0;left:var(--desktop-sidebar-width);border-left:solid 1px var(--sidebar-resizer-hover);}.src-sidebar-expanded .rustdoc.src .sidebar-resizer:hover,.src-sidebar-expanded .rustdoc.src .sidebar-resizer:active,.src-sidebar-expanded .rustdoc.src .sidebar-resizer:focus,.src-sidebar-expanded .rustdoc.src .sidebar-resizer.active{left:calc(var(--src-sidebar-width) - 1px);}@media (pointer:coarse){.sidebar-resizer{display:none !important;}}.sidebar-resizer.active{padding:0 140px;width:2px;margin-left:-140px;border-left:none;}.sidebar-resizer.active:before{border-left:solid 2px var(--sidebar-resizer-active);display:block;height:100%;content:"";}.sidebar,.mobile-topbar,.sidebar-menu-toggle,#src-sidebar{background-color:var(--sidebar-background-color);}.src .sidebar>*{visibility:hidden;}.src-sidebar-expanded .src .sidebar{overflow-y:auto;flex-basis:var(--src-sidebar-width);width:var(--src-sidebar-width);}.src-sidebar-expanded .src .sidebar>*{visibility:visible;}#all-types{margin-top:1em;}*{scrollbar-width:initial;scrollbar-color:var(--scrollbar-color);}.sidebar{scrollbar-width:thin;scrollbar-color:var(--scrollbar-color);}::-webkit-scrollbar{width:12px;}.sidebar::-webkit-scrollbar{width:8px;}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0;background-color:var(--scrollbar-track-background-color);}.sidebar::-webkit-scrollbar-track{background-color:var(--scrollbar-track-background-color);}::-webkit-scrollbar-thumb,.sidebar::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb-background-color);}.hidden{display:none !important;}.logo-container>img{height:48px;width:48px;}ul.block,.block li{padding:0;margin:0;list-style:none;}.sidebar-elems a,.sidebar>h2 a{display:block;padding:0.25rem;margin-left:-0.25rem;margin-right:0.25rem;}.sidebar h2{overflow-wrap:anywhere;padding:0;margin:0.7rem 0;}.sidebar h3{font-size:1.125rem;padding:0;margin:0;}.sidebar-elems,.sidebar>.version,.sidebar>h2{padding-left:24px;}.sidebar a{color:var(--sidebar-link-color);}.sidebar .current,.sidebar .current a,.sidebar-crate a.logo-container:hover+h2 a,.sidebar a:hover:not(.logo-container){background-color:var(--sidebar-current-link-background-color);}.sidebar-elems .block{margin-bottom:2em;}.sidebar-elems .block li a{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}.sidebar-crate{display:flex;align-items:center;justify-content:center;margin:14px 32px 1rem;row-gap:10px;column-gap:32px;flex-wrap:wrap;}.sidebar-crate h2{flex-grow:1;margin:0 -8px;align-self:start;}.sidebar-crate .logo-container{margin:0 -16px 0 -16px;text-align:center;}.sidebar-crate h2 a{display:block;margin:0 calc(-24px + 0.25rem) 0 -0.2rem;padding:calc((16px - 0.57rem ) / 2 ) 0.25rem;padding-left:0.2rem;}.sidebar-crate h2 .version{display:block;font-weight:normal;font-size:1rem;overflow-wrap:break-word;}.sidebar-crate+.version{margin-top:-1rem;margin-bottom:1rem;}.mobile-topbar{display:none;}.rustdoc .example-wrap{display:flex;position:relative;margin-bottom:10px;}.rustdoc .example-wrap:last-child{margin-bottom:0px;}.rustdoc .example-wrap pre{margin:0;flex-grow:1;}.rustdoc:not(.src) .example-wrap pre{overflow:auto hidden;}.rustdoc .example-wrap pre.example-line-numbers,.rustdoc .example-wrap pre.src-line-numbers{flex-grow:0;min-width:fit-content;overflow:initial;text-align:right;-webkit-user-select:none;user-select:none;padding:14px 8px;color:var(--src-line-numbers-span-color);}.rustdoc .example-wrap pre.src-line-numbers{padding:14px 0;}.src-line-numbers a,.src-line-numbers span{color:var(--src-line-numbers-span-color);padding:0 8px;}.src-line-numbers :target{background-color:transparent;border-right:none;padding:0 8px;}.src-line-numbers .line-highlighted{background-color:var(--src-line-number-highlighted-background-color);}.search-loading{text-align:center;}.docblock-short{overflow-wrap:break-word;overflow-wrap:anywhere;}.docblock :not(pre)>code,.docblock-short code{white-space:pre-wrap;}.top-doc .docblock h2{font-size:1.375rem;}.top-doc .docblock h3{font-size:1.25rem;}.top-doc .docblock h4,.top-doc .docblock h5{font-size:1.125rem;}.top-doc .docblock h6{font-size:1rem;}.docblock h5{font-size:1rem;}.docblock h6{font-size:0.875rem;}.docblock{margin-left:24px;position:relative;}.docblock>:not(.more-examples-toggle):not(.example-wrap){max-width:100%;overflow-x:auto;}.out-of-band{flex-grow:0;font-size:1.125rem;}.docblock code,.docblock-short code,pre,.rustdoc.src .example-wrap{background-color:var(--code-block-background-color);}#main-content{position:relative;}.docblock table{margin:.5em 0;border-collapse:collapse;}.docblock table td,.docblock table th{padding:.5em;border:1px solid var(--border-color);}.docblock table tbody tr:nth-child(2n){background:var(--table-alt-row-background-color);}div.where{white-space:pre-wrap;font-size:0.875rem;}.item-info{display:block;margin-left:24px;}.item-info code{font-size:0.875rem;}#main-content>.item-info{margin-left:0;}nav.sub{flex-grow:1;flex-flow:row nowrap;margin:4px 0 25px 0;display:flex;align-items:center;}.search-form{position:relative;display:flex;height:34px;flex-grow:1;}.src nav.sub{margin:0 0 15px 0;}.section-header{display:block;position:relative;}.section-header:hover>.anchor,.impl:hover>.anchor,.trait-impl:hover>.anchor,.variant:hover>.anchor{display:initial;}.anchor{display:none;position:absolute;left:-0.5em;background:none !important;}.anchor.field{left:-5px;}.section-header>.anchor{left:-15px;padding-right:8px;}h2.section-header>.anchor{padding-right:6px;}a.doc-anchor{color:var(--main-color);display:none;position:absolute;left:-17px;padding-right:5px;padding-left:3px;}*:hover>.doc-anchor{display:block;}.top-doc>.docblock>*:first-child>.doc-anchor{display:none !important;}.main-heading a:hover,.example-wrap .rust a:hover,.all-items a:hover,.docblock a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover:not(.doc-anchor),.docblock-short a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,.item-info a{text-decoration:underline;}.crate.block li.current a{font-weight:500;}table,.item-table{overflow-wrap:break-word;}.item-table{display:table;padding:0;margin:0;}.item-table>li{display:table-row;}.item-table>li>div{display:table-cell;}.item-table>li>.item-name{padding-right:1.25rem;}.search-results-title{margin-top:0;white-space:nowrap;display:flex;align-items:baseline;}#crate-search-div{position:relative;min-width:5em;}#crate-search{min-width:115px;padding:0 23px 0 4px;max-width:100%;text-overflow:ellipsis;border:1px solid var(--border-color);border-radius:4px;outline:none;cursor:pointer;-moz-appearance:none;-webkit-appearance:none;text-indent:0.01px;background-color:var(--main-background-color);color:inherit;line-height:1.5;font-weight:500;}#crate-search:hover,#crate-search:focus{border-color:var(--crate-search-hover-border);}#crate-search-div::after{pointer-events:none;width:100%;height:100%;position:absolute;top:0;left:0;content:"";background-repeat:no-repeat;background-size:20px;background-position:calc(100% - 2px) 56%;background-image:url('data:image/svg+xml, \ + ');filter:var(--crate-search-div-filter);}#crate-search-div:hover::after,#crate-search-div:focus-within::after{filter:var(--crate-search-div-hover-filter);}#crate-search>option{font-size:1rem;}.search-input{-webkit-appearance:none;outline:none;border:1px solid var(--border-color);border-radius:2px;padding:8px;font-size:1rem;flex-grow:1;background-color:var(--button-background-color);color:var(--search-color);}.search-input:focus{border-color:var(--search-input-focused-border-color);}.search-results{display:none;}.search-results.active{display:block;}.search-results>a{display:flex;margin-left:2px;margin-right:2px;border-bottom:1px solid var(--search-result-border-color);gap:1em;}.search-results>a>div.desc{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex:2;}.search-results a:hover,.search-results a:focus{background-color:var(--search-result-link-focus-background-color);}.search-results .result-name{display:flex;align-items:center;justify-content:start;flex:3;}.search-results .result-name .alias{color:var(--search-results-alias-color);}.search-results .result-name .grey{color:var(--search-results-grey-color);}.search-results .result-name .typename{color:var(--search-results-grey-color);font-size:0.875rem;width:var(--search-typename-width);}.search-results .result-name .path{word-break:break-all;max-width:calc(100% - var(--search-typename-width));display:inline-block;}.search-results .result-name .path>*{display:inline;}.popover{position:absolute;top:100%;right:0;z-index:calc(var(--desktop-sidebar-z-index) + 1);margin-top:7px;border-radius:3px;border:1px solid var(--border-color);background-color:var(--main-background-color);color:var(--main-color);--popover-arrow-offset:11px;}.popover::before{content:'';position:absolute;right:var(--popover-arrow-offset);border:solid var(--border-color);border-width:1px 1px 0 0;background-color:var(--main-background-color);padding:4px;transform:rotate(-45deg);top:-5px;}.setting-line{margin:1.2em 0.6em;}.setting-radio input,.setting-check input{margin-right:0.3em;height:1.2rem;width:1.2rem;border:2px solid var(--settings-input-border-color);outline:none;-webkit-appearance:none;cursor:pointer;}.setting-radio input{border-radius:50%;}.setting-radio span,.setting-check span{padding-bottom:1px;}.setting-radio{margin-top:0.1em;margin-bottom:0.1em;min-width:3.8em;padding:0.3em;display:inline-flex;align-items:center;cursor:pointer;}.setting-radio+.setting-radio{margin-left:0.5em;}.setting-check{margin-right:20px;display:flex;align-items:center;cursor:pointer;}.setting-radio input:checked{box-shadow:inset 0 0 0 3px var(--main-background-color);background-color:var(--settings-input-color);}.setting-check input:checked{background-color:var(--settings-input-color);border-width:1px;content:url('data:image/svg+xml,\ + \ + ');}.setting-radio input:focus,.setting-check input:focus{box-shadow:0 0 1px 1px var(--settings-input-color);}.setting-radio input:checked:focus{box-shadow:inset 0 0 0 3px var(--main-background-color),0 0 2px 2px var(--settings-input-color);}.setting-radio input:hover,.setting-check input:hover{border-color:var(--settings-input-color) !important;}#help.popover{max-width:600px;--popover-arrow-offset:48px;}#help dt{float:left;clear:left;margin-right:0.5rem;}#help span.top,#help span.bottom{text-align:center;display:block;font-size:1.125rem;}#help span.top{margin:10px 0;border-bottom:1px solid var(--border-color);padding-bottom:4px;margin-bottom:6px;}#help span.bottom{clear:both;border-top:1px solid var(--border-color);}.side-by-side>div{width:50%;float:left;padding:0 20px 20px 17px;}.item-info .stab{display:block;padding:3px;margin-bottom:5px;}.item-name .stab{margin-left:0.3125em;}.stab{padding:0 2px;font-size:0.875rem;font-weight:normal;color:var(--main-color);background-color:var(--stab-background-color);width:fit-content;white-space:pre-wrap;border-radius:3px;display:inline;vertical-align:baseline;}.stab.portability>code{background:none;color:var(--stab-code-color);}.stab .emoji,.item-info .stab::before{font-size:1.25rem;}.stab .emoji{margin-right:0.3rem;}.item-info .stab::before{content:"\0";width:0;display:inline-block;color:transparent;}.emoji{text-shadow:1px 0 0 black,-1px 0 0 black,0 1px 0 black,0 -1px 0 black;}.since{font-weight:normal;font-size:initial;}.rightside{padding-left:12px;float:right;}.rightside:not(a),.out-of-band{color:var(--right-side-color);}pre.rust{tab-size:4;-moz-tab-size:4;}pre.rust .kw{color:var(--code-highlight-kw-color);}pre.rust .kw-2{color:var(--code-highlight-kw-2-color);}pre.rust .lifetime{color:var(--code-highlight-lifetime-color);}pre.rust .prelude-ty{color:var(--code-highlight-prelude-color);}pre.rust .prelude-val{color:var(--code-highlight-prelude-val-color);}pre.rust .string{color:var(--code-highlight-string-color);}pre.rust .number{color:var(--code-highlight-number-color);}pre.rust .bool-val{color:var(--code-highlight-literal-color);}pre.rust .self{color:var(--code-highlight-self-color);}pre.rust .attr{color:var(--code-highlight-attribute-color);}pre.rust .macro,pre.rust .macro-nonterminal{color:var(--code-highlight-macro-color);}pre.rust .question-mark{font-weight:bold;color:var(--code-highlight-question-mark-color);}pre.rust .comment{color:var(--code-highlight-comment-color);}pre.rust .doccomment{color:var(--code-highlight-doc-comment-color);}.rustdoc.src .example-wrap pre.rust a{background:var(--codeblock-link-background);}.example-wrap.compile_fail,.example-wrap.should_panic{border-left:2px solid var(--codeblock-error-color);}.ignore.example-wrap{border-left:2px solid var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover,.example-wrap.should_panic:hover{border-left:2px solid var(--codeblock-error-hover-color);}.example-wrap.ignore:hover{border-left:2px solid var(--codeblock-ignore-hover-color);}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip{color:var(--codeblock-error-color);}.example-wrap.ignore .tooltip{color:var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover .tooltip,.example-wrap.should_panic:hover .tooltip{color:var(--codeblock-error-hover-color);}.example-wrap.ignore:hover .tooltip{color:var(--codeblock-ignore-hover-color);}.example-wrap .tooltip{position:absolute;display:block;left:-25px;top:5px;margin:0;line-height:1;}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip,.example-wrap.ignore .tooltip{font-weight:bold;font-size:1.25rem;}.content .docblock .warning{border-left:2px solid var(--warning-border-color);padding:14px;position:relative;overflow-x:visible !important;}.content .docblock .warning::before{color:var(--warning-border-color);content:"ⓘ";position:absolute;left:-25px;top:5px;font-weight:bold;font-size:1.25rem;}.top-doc>.docblock>.warning:first-child::before{top:20px;}a.test-arrow{visibility:hidden;position:absolute;padding:5px 10px 5px 10px;border-radius:5px;font-size:1.375rem;top:5px;right:5px;z-index:1;color:var(--test-arrow-color);background-color:var(--test-arrow-background-color);}a.test-arrow:hover{color:var(--test-arrow-hover-color);background-color:var(--test-arrow-hover-background-color);}.example-wrap:hover .test-arrow{visibility:visible;}.code-attribute{font-weight:300;color:var(--code-attribute-color);}.item-spacer{width:100%;height:12px;display:block;}.out-of-band>span.since{font-size:1.25rem;}.sub-variant h4{font-size:1rem;font-weight:400;margin-top:0;margin-bottom:0;}.sub-variant{margin-left:24px;margin-bottom:40px;}.sub-variant>.sub-variant-field{margin-left:24px;}:target{padding-right:3px;background-color:var(--target-background-color);border-right:3px solid var(--target-border-color);}.code-header a.tooltip{color:inherit;margin-right:15px;position:relative;}.code-header a.tooltip:hover{color:var(--link-color);}a.tooltip:hover::after{position:absolute;top:calc(100% - 10px);left:-15px;right:-15px;height:20px;content:"\00a0";}.fade-out{opacity:0;transition:opacity 0.45s cubic-bezier(0,0,0.1,1.0);}.popover.tooltip .content{margin:0.25em 0.5em;}.popover.tooltip .content pre,.popover.tooltip .content code{background:transparent;margin:0;padding:0;font-size:1.25rem;white-space:pre-wrap;}.popover.tooltip .content>h3:first-child{margin:0 0 5px 0;}.search-failed{text-align:center;margin-top:20px;display:none;}.search-failed.active{display:block;}.search-failed>ul{text-align:left;max-width:570px;margin-left:auto;margin-right:auto;}#search-tabs{display:flex;flex-direction:row;gap:1px;margin-bottom:4px;}#search-tabs button{text-align:center;font-size:1.125rem;border:0;border-top:2px solid;flex:1;line-height:1.5;color:inherit;}#search-tabs button:not(.selected){background-color:var(--search-tab-button-not-selected-background);border-top-color:var(--search-tab-button-not-selected-border-top-color);}#search-tabs button:hover,#search-tabs button.selected{background-color:var(--search-tab-button-selected-background);border-top-color:var(--search-tab-button-selected-border-top-color);}#search-tabs .count{font-size:1rem;font-variant-numeric:tabular-nums;color:var(--search-tab-title-count-color);}#search .error code{border-radius:3px;background-color:var(--search-error-code-background-color);}.search-corrections{font-weight:normal;}#src-sidebar{width:100%;overflow:auto;}#src-sidebar div.files>a:hover,details.dir-entry summary:hover,#src-sidebar div.files>a:focus,details.dir-entry summary:focus{background-color:var(--src-sidebar-background-hover);}#src-sidebar div.files>a.selected{background-color:var(--src-sidebar-background-selected);}.src-sidebar-title{position:sticky;top:0;display:flex;padding:8px 8px 0 48px;margin-bottom:7px;background:var(--sidebar-background-color);border-bottom:1px solid var(--border-color);}#settings-menu,#help-button{margin-left:4px;display:flex;}#sidebar-button{display:none;line-height:0;}.hide-sidebar #sidebar-button,.src #sidebar-button{display:flex;margin-right:4px;position:fixed;left:6px;height:34px;width:34px;background-color:var(--main-background-color);z-index:1;}.src #sidebar-button{left:8px;z-index:calc(var(--desktop-sidebar-z-index) + 1);}.hide-sidebar .src #sidebar-button{position:static;}#settings-menu>a,#help-button>a,#sidebar-button>a{display:flex;align-items:center;justify-content:center;background-color:var(--button-background-color);border:1px solid var(--border-color);border-radius:2px;color:var(--settings-button-color);font-size:20px;width:33px;}#settings-menu>a:hover,#settings-menu>a:focus,#help-button>a:hover,#help-button>a:focus,#sidebar-button>a:hover,#sidebar-button>a:focus{border-color:var(--settings-button-border-focus);}#sidebar-button>a:before{content:url('data:image/svg+xml,\ + \ + \ + ');width:22px;height:22px;}#copy-path{color:var(--copy-path-button-color);background:var(--main-background-color);height:34px;margin-left:10px;padding:0;padding-left:2px;border:0;width:33px;}#copy-path>img{filter:var(--copy-path-img-filter);}#copy-path:hover>img{filter:var(--copy-path-img-hover-filter);}@keyframes rotating{from{transform:rotate(0deg);}to{transform:rotate(360deg);}}#settings-menu.rotate>a img{animation:rotating 2s linear infinite;}kbd{display:inline-block;padding:3px 5px;font:15px monospace;line-height:10px;vertical-align:middle;border:solid 1px var(--border-color);border-radius:3px;color:var(--kbd-color);background-color:var(--kbd-background);box-shadow:inset 0 -1px 0 var(--kbd-box-shadow-color);}ul.all-items>li{list-style:none;}details.dir-entry{padding-left:4px;}details.dir-entry>summary{margin:0 0 0 -4px;padding:0 0 0 4px;cursor:pointer;}details.dir-entry div.folders,details.dir-entry div.files{padding-left:23px;}details.dir-entry a{display:block;}details.toggle{contain:layout;position:relative;}details.toggle>summary.hideme{cursor:pointer;font-size:1rem;}details.toggle>summary{list-style:none;outline:none;}details.toggle>summary::-webkit-details-marker,details.toggle>summary::marker{display:none;}details.toggle>summary.hideme>span{margin-left:9px;}details.toggle>summary::before{background:url('data:image/svg+xml,') no-repeat top left;content:"";cursor:pointer;width:16px;height:16px;display:inline-block;vertical-align:middle;opacity:.5;filter:var(--toggle-filter);}details.toggle>summary.hideme>span,.more-examples-toggle summary,.more-examples-toggle .hide-more{color:var(--toggles-color);}details.toggle>summary::after{content:"Expand";overflow:hidden;width:0;height:0;position:absolute;}details.toggle>summary.hideme::after{content:"";}details.toggle>summary:focus::before,details.toggle>summary:hover::before{opacity:1;}details.toggle>summary:focus-visible::before{outline:1px dotted #000;outline-offset:1px;}details.non-exhaustive{margin-bottom:8px;}details.toggle>summary.hideme::before{position:relative;}details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;top:4px;}.impl-items>details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;}details.toggle[open] >summary.hideme{position:absolute;}details.toggle[open] >summary.hideme>span{display:none;}details.toggle[open] >summary::before{background:url('data:image/svg+xml,') no-repeat top left;}details.toggle[open] >summary::after{content:"Collapse";}.docblock summary>*{display:inline-block;}.docblock>.example-wrap:first-child .tooltip{margin-top:16px;}.src #sidebar-button>a:before,.sidebar-menu-toggle:before{content:url('data:image/svg+xml,\ + ');opacity:0.75;}.sidebar-menu-toggle:hover:before,.sidebar-menu-toggle:active:before,.sidebar-menu-toggle:focus:before{opacity:1;}.src #sidebar-button>a:before{content:url('data:image/svg+xml,\ + \ + \ + ');opacity:0.75;}@media (max-width:850px){#search-tabs .count{display:block;}}@media (max-width:700px){*[id]{scroll-margin-top:45px;}.rustdoc{display:block;}main{padding-left:15px;padding-top:0px;}.main-heading{flex-direction:column;}.out-of-band{text-align:left;margin-left:initial;padding:initial;}.out-of-band .since::before{content:"Since ";}.sidebar .logo-container,.sidebar .location,.sidebar-resizer{display:none;}.sidebar{position:fixed;top:45px;left:-1000px;z-index:11;height:calc(100vh - 45px);width:200px;}.src main,.rustdoc.src .sidebar{top:0;padding:0;height:100vh;border:0;}.src .search-form{margin-left:40px;}.hide-sidebar .search-form{margin-left:32px;}.hide-sidebar .src .search-form{margin-left:0;}.sidebar.shown,.src-sidebar-expanded .src .sidebar,.rustdoc:not(.src) .sidebar:focus-within{left:0;}.mobile-topbar h2{padding-bottom:0;margin:auto 0.5em auto auto;overflow:hidden;font-size:24px;}.mobile-topbar h2 a{display:block;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;}.mobile-topbar .logo-container>img{max-width:35px;max-height:35px;margin:5px 0 5px 20px;}.mobile-topbar{display:flex;flex-direction:row;position:sticky;z-index:10;font-size:2rem;height:45px;width:100%;left:0;top:0;}.hide-sidebar .mobile-topbar{display:none;}.sidebar-menu-toggle{width:45px;border:none;line-height:0;}.hide-sidebar .sidebar-menu-toggle{display:none;}.sidebar-elems{margin-top:1em;}.anchor{display:none !important;}#main-content>details.toggle>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}#copy-path,#help-button{display:none;}#sidebar-button>a:before{content:url('data:image/svg+xml,\ + \ + \ + ');width:22px;height:22px;}.sidebar-menu-toggle:before{filter:var(--mobile-sidebar-menu-filter);}.sidebar-menu-toggle:hover{background:var(--main-background-color);}.item-table,.item-row,.item-table>li,.item-table>li>div,.search-results>a,.search-results>a>div{display:block;}.search-results>a{padding:5px 0px;}.search-results>a>div.desc,.item-table>li>div.desc{padding-left:2em;}.search-results .result-name{display:block;}.search-results .result-name .typename{width:initial;margin-right:0;}.search-results .result-name .typename,.search-results .result-name .path{display:inline;}.src-sidebar-expanded .src .sidebar{position:fixed;max-width:100vw;width:100vw;}.src .src-sidebar-title{padding-top:0;}details.toggle:not(.top-doc)>summary{margin-left:10px;}.impl-items>details.toggle>summary:not(.hideme)::before,#main-content>details.toggle:not(.top-doc)>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}.impl-items>.item-info{margin-left:34px;}.src nav.sub{margin:0;padding:var(--nav-sub-mobile-padding);}}@media (min-width:701px){.scraped-example-title{position:absolute;z-index:10;background:var(--main-background-color);bottom:8px;right:5px;padding:2px 4px;box-shadow:0 0 4px var(--main-background-color);}}@media print{nav.sidebar,nav.sub,.out-of-band,a.src,#copy-path,details.toggle[open] >summary::before,details.toggle>summary::before,details.toggle.top-doc>summary{display:none;}.docblock{margin-left:0;}main{padding:10px;}}@media (max-width:464px){.docblock{margin-left:12px;}.docblock code{overflow-wrap:break-word;overflow-wrap:anywhere;}nav.sub{flex-direction:column;}.search-form{align-self:stretch;}}.variant,.implementors-toggle>summary,.impl,#implementors-list>.docblock,.impl-items>section,.impl-items>.toggle>summary,.methods>section,.methods>.toggle>summary{margin-bottom:0.75em;}.variants>.docblock,.implementors-toggle>.docblock,.impl-items>.toggle[open]:not(:last-child),.methods>.toggle[open]:not(:last-child),.implementors-toggle[open]:not(:last-child){margin-bottom:2em;}#trait-implementations-list .impl-items>.toggle:not(:last-child),#synthetic-implementations-list .impl-items>.toggle:not(:last-child),#blanket-implementations-list .impl-items>.toggle:not(:last-child){margin-bottom:1em;}.scraped-example-list .scrape-help{margin-left:10px;padding:0 4px;font-weight:normal;font-size:12px;position:relative;bottom:1px;border:1px solid var(--scrape-example-help-border-color);border-radius:50px;color:var(--scrape-example-help-color);}.scraped-example-list .scrape-help:hover{border-color:var(--scrape-example-help-hover-border-color);color:var(--scrape-example-help-hover-color);}.scraped-example{position:relative;}.scraped-example .code-wrapper{position:relative;display:flex;flex-direction:row;flex-wrap:wrap;width:100%;}.scraped-example:not(.expanded) .code-wrapper{max-height:calc(1.5em * 5 + 10px);}.scraped-example:not(.expanded) .code-wrapper pre{overflow-y:hidden;padding-bottom:0;max-height:calc(1.5em * 5 + 10px);}.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper,.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper pre{max-height:calc(1.5em * 10 + 10px);}.scraped-example .code-wrapper .next,.scraped-example .code-wrapper .prev,.scraped-example .code-wrapper .expand{color:var(--main-color);position:absolute;top:0.25em;z-index:1;padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.scraped-example .code-wrapper .prev{right:2.25em;}.scraped-example .code-wrapper .next{right:1.25em;}.scraped-example .code-wrapper .expand{right:0.25em;}.scraped-example:not(.expanded) .code-wrapper::before,.scraped-example:not(.expanded) .code-wrapper::after{content:" ";width:100%;height:5px;position:absolute;z-index:1;}.scraped-example:not(.expanded) .code-wrapper::before{top:0;background:linear-gradient(to bottom,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example:not(.expanded) .code-wrapper::after{bottom:0;background:linear-gradient(to top,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example .code-wrapper .example-wrap{width:100%;overflow-y:hidden;margin-bottom:0;}.scraped-example:not(.expanded) .code-wrapper .example-wrap{overflow-x:hidden;}.scraped-example .example-wrap .rust span.highlight{background:var(--scrape-example-code-line-highlight);}.scraped-example .example-wrap .rust span.highlight.focus{background:var(--scrape-example-code-line-highlight-focus);}.more-examples-toggle{max-width:calc(100% + 25px);margin-top:10px;margin-left:-25px;}.more-examples-toggle .hide-more{margin-left:25px;cursor:pointer;}.more-scraped-examples{margin-left:25px;position:relative;}.toggle-line{position:absolute;top:5px;bottom:0;right:calc(100% + 10px);padding:0 4px;cursor:pointer;}.toggle-line-inner{min-width:2px;height:100%;background:var(--scrape-example-toggle-line-background);}.toggle-line:hover .toggle-line-inner{background:var(--scrape-example-toggle-line-hover-background);}.more-scraped-examples .scraped-example,.example-links{margin-top:20px;}.more-scraped-examples .scraped-example:first-child{margin-top:5px;}.example-links ul{margin-bottom:0;}:root[data-theme="light"]{--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#f5f5f5;--sidebar-background-color-hover:#e0e0e0;--code-block-background-color:#f5f5f5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--mobile-sidebar-menu-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#fff;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--src-sidebar-background-selected:#fff;--src-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#f5f5f5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);--sidebar-resizer-hover:hsl(207,90%,66%);--sidebar-resizer-active:hsl(207,90%,54%);}:root[data-theme="dark"]{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--mobile-sidebar-menu-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--src-sidebar-background-selected:#333;--src-sidebar-background-hover:#444;--table-alt-row-background-color:#2a2a2a;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);--sidebar-resizer-hover:hsl(207,30%,54%);--sidebar-resizer-active:hsl(207,90%,54%);}:root[data-theme="ayu"]{--main-background-color:#0f1419;--main-color:#c5c5c5;--settings-input-color:#ffb454;--settings-input-border-color:#999;--settings-button-color:#fff;--settings-button-border-focus:#e0e0e0;--sidebar-background-color:#14191f;--sidebar-background-color-hover:rgba(70,70,70,0.33);--code-block-background-color:#191f26;--scrollbar-track-background-color:transparent;--scrollbar-thumb-background-color:#5c6773;--scrollbar-color:#5c6773 #24292f;--headings-border-bottom-color:#5c6773;--border-color:#5c6773;--button-background-color:#141920;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--mobile-sidebar-menu-filter:invert(100%);--search-input-focused-border-color:#5c6773;--copy-path-button-color:#fff;--copy-path-img-filter:invert(70%);--copy-path-img-hover-filter:invert(100%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ffa0a5;--trait-link-color:#39afd7;--assoc-item-link-color:#39afd7;--function-link-color:#fdd687;--macro-link-color:#a37acc;--keyword-link-color:#39afd7;--mod-link-color:#39afd7;--link-color:#39afd7;--sidebar-link-color:#53b1db;--sidebar-current-link-background-color:transparent;--search-result-link-focus-background-color:#3c3c3c;--search-result-border-color:#aaa3;--search-color:#fff;--search-error-code-background-color:#4f4c4c;--search-results-alias-color:#c5c5c5;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:none;--search-tab-button-not-selected-background:transparent !important;--search-tab-button-selected-border-top-color:none;--search-tab-button-selected-background:#141920 !important;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ff7733;--code-highlight-kw-2-color:#ff7733;--code-highlight-lifetime-color:#ff7733;--code-highlight-prelude-color:#69f2df;--code-highlight-prelude-val-color:#ff7733;--code-highlight-number-color:#b8cc52;--code-highlight-string-color:#b8cc52;--code-highlight-literal-color:#ff7733;--code-highlight-attribute-color:#e6e1cf;--code-highlight-self-color:#36a3d9;--code-highlight-macro-color:#a37acc;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#788797;--code-highlight-doc-comment-color:#a1ac88;--src-line-numbers-span-color:#5c6773;--src-line-number-highlighted-background-color:rgba(255,236,164,0.06);--test-arrow-color:#788797;--test-arrow-background-color:rgba(57,175,215,0.09);--test-arrow-hover-color:#c5c5c5;--test-arrow-hover-background-color:rgba(57,175,215,0.368);--target-background-color:rgba(255,236,164,0.06);--target-border-color:rgba(255,180,76,0.85);--kbd-color:#c5c5c5;--kbd-background:#314559;--kbd-box-shadow-color:#5c6773;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(41%) sepia(12%) saturate(487%) hue-rotate(171deg) brightness(94%) contrast(94%);--crate-search-div-hover-filter:invert(98%) sepia(12%) saturate(81%) hue-rotate(343deg) brightness(113%) contrast(76%);--crate-search-hover-border:#e0e0e0;--src-sidebar-background-selected:#14191f;--src-sidebar-background-hover:#14191f;--table-alt-row-background-color:#191f26;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(15,20,25,1);--scrape-example-code-wrapper-background-end:rgba(15,20,25,0);--sidebar-resizer-hover:hsl(34,50%,33%);--sidebar-resizer-active:hsl(34,100%,66%);}:root[data-theme="ayu"] h1,:root[data-theme="ayu"] h2,:root[data-theme="ayu"] h3,:root[data-theme="ayu"] h4,:where(:root[data-theme="ayu"]) h1 a,:root[data-theme="ayu"] .sidebar h2 a,:root[data-theme="ayu"] .sidebar h3 a{color:#fff;}:root[data-theme="ayu"] .docblock code{color:#ffb454;}:root[data-theme="ayu"] .docblock a>code{color:#39AFD7 !important;}:root[data-theme="ayu"] .code-header,:root[data-theme="ayu"] .docblock pre>code,:root[data-theme="ayu"] pre,:root[data-theme="ayu"] pre>code,:root[data-theme="ayu"] .item-info code,:root[data-theme="ayu"] .rustdoc.source .example-wrap{color:#e6e1cf;}:root[data-theme="ayu"] .sidebar .current,:root[data-theme="ayu"] .sidebar .current a,:root[data-theme="ayu"] .sidebar a:hover,:root[data-theme="ayu"] #src-sidebar div.files>a:hover,:root[data-theme="ayu"] details.dir-entry summary:hover,:root[data-theme="ayu"] #src-sidebar div.files>a:focus,:root[data-theme="ayu"] details.dir-entry summary:focus,:root[data-theme="ayu"] #src-sidebar div.files>a.selected{color:#ffb44c;}:root[data-theme="ayu"] .sidebar-elems .location{color:#ff7733;}:root[data-theme="ayu"] .src-line-numbers .line-highlighted{color:#708090;padding-right:7px;border-right:1px solid #ffb44c;}:root[data-theme="ayu"] .search-results a:hover,:root[data-theme="ayu"] .search-results a:focus{color:#fff !important;background-color:#3c3c3c;}:root[data-theme="ayu"] .search-results a{color:#0096cf;}:root[data-theme="ayu"] .search-results a div.desc{color:#c5c5c5;}:root[data-theme="ayu"] .result-name .primitive>i,:root[data-theme="ayu"] .result-name .keyword>i{color:#788797;}:root[data-theme="ayu"] #search-tabs>button.selected{border-bottom:1px solid #ffb44c !important;border-top:none;}:root[data-theme="ayu"] #search-tabs>button:not(.selected){border:none;background-color:transparent !important;}:root[data-theme="ayu"] #search-tabs>button:hover{border-bottom:1px solid rgba(242,151,24,0.3);}:root[data-theme="ayu"] #settings-menu>a img,:root[data-theme="ayu"] #sidebar-button>a:before{filter:invert(100);} \ No newline at end of file diff --git a/docs/static.files/search-dd67cee4cfa65049.js b/docs/static.files/search-dd67cee4cfa65049.js new file mode 100644 index 00000000..ef8bf865 --- /dev/null +++ b/docs/static.files/search-dd67cee4cfa65049.js @@ -0,0 +1,5 @@ +"use strict";if(!Array.prototype.toSpliced){Array.prototype.toSpliced=function(){const me=this.slice();Array.prototype.splice.apply(me,arguments);return me}}(function(){const itemTypes=["keyword","primitive","mod","externcrate","import","struct","enum","fn","type","static","trait","impl","tymethod","method","structfield","variant","macro","associatedtype","constant","associatedconstant","union","foreigntype","existential","attr","derive","traitalias","generic",];const longItemTypes=["keyword","primitive type","module","extern crate","re-export","struct","enum","function","type alias","static","trait","","trait method","method","struct field","enum variant","macro","assoc type","constant","assoc const","union","foreign type","existential type","attribute macro","derive macro","trait alias",];const TY_GENERIC=itemTypes.indexOf("generic");const ROOT_PATH=typeof window!=="undefined"?window.rootPath:"../";function printTab(nb){let iter=0;let foundCurrentTab=false;let foundCurrentResultSet=false;onEachLazy(document.getElementById("search-tabs").childNodes,elem=>{if(nb===iter){addClass(elem,"selected");foundCurrentTab=true}else{removeClass(elem,"selected")}iter+=1});const isTypeSearch=(nb>0||iter===1);iter=0;onEachLazy(document.getElementById("results").childNodes,elem=>{if(nb===iter){addClass(elem,"active");foundCurrentResultSet=true}else{removeClass(elem,"active")}iter+=1});if(foundCurrentTab&&foundCurrentResultSet){searchState.currentTab=nb;const correctionsElem=document.getElementsByClassName("search-corrections");if(isTypeSearch){removeClass(correctionsElem[0],"hidden")}else{addClass(correctionsElem[0],"hidden")}}else if(nb!==0){printTab(0)}}const editDistanceState={current:[],prev:[],prevPrev:[],calculate:function calculate(a,b,limit){if(a.lengthlimit){return limit+1}while(b.length>0&&b[0]===a[0]){a=a.substring(1);b=b.substring(1)}while(b.length>0&&b[b.length-1]===a[a.length-1]){a=a.substring(0,a.length-1);b=b.substring(0,b.length-1)}if(b.length===0){return minDist}const aLength=a.length;const bLength=b.length;for(let i=0;i<=bLength;++i){this.current[i]=0;this.prev[i]=i;this.prevPrev[i]=Number.MAX_VALUE}for(let i=1;i<=aLength;++i){this.current[0]=i;const aIdx=i-1;for(let j=1;j<=bLength;++j){const bIdx=j-1;const substitutionCost=a[aIdx]===b[bIdx]?0:1;this.current[j]=Math.min(this.prev[j]+1,this.current[j-1]+1,this.prev[j-1]+substitutionCost);if((i>1)&&(j>1)&&(a[aIdx]===b[bIdx-1])&&(a[aIdx-1]===b[bIdx])){this.current[j]=Math.min(this.current[j],this.prevPrev[j-2]+1)}}const prevPrevTmp=this.prevPrev;this.prevPrev=this.prev;this.prev=this.current;this.current=prevPrevTmp}const distance=this.prev[bLength];return distance<=limit?distance:(limit+1)},};function editDistance(a,b,limit){return editDistanceState.calculate(a,b,limit)}function initSearch(rawSearchIndex){const MAX_RESULTS=200;const NO_TYPE_FILTER=-1;let searchIndex;let functionTypeFingerprint;let currentResults;let typeNameIdMap;const ALIASES=new Map();let typeNameIdOfArray;let typeNameIdOfSlice;let typeNameIdOfArrayOrSlice;let typeNameIdOfTuple;let typeNameIdOfUnit;let typeNameIdOfTupleOrUnit;function buildTypeMapIndex(name,isAssocType){if(name===""||name===null){return null}if(typeNameIdMap.has(name)){const obj=typeNameIdMap.get(name);obj.assocOnly=isAssocType&&obj.assocOnly;return obj.id}else{const id=typeNameIdMap.size;typeNameIdMap.set(name,{id,assocOnly:isAssocType});return id}}function isSpecialStartCharacter(c){return"<\"".indexOf(c)!==-1}function isEndCharacter(c){return"=,>-])".indexOf(c)!==-1}function itemTypeFromName(typename){const index=itemTypes.findIndex(i=>i===typename);if(index<0){throw["Unknown type filter ",typename]}return index}function getStringElem(query,parserState,isInGenerics){if(isInGenerics){throw["Unexpected ","\""," in generics"]}else if(query.literalSearch){throw["Cannot have more than one literal search element"]}else if(parserState.totalElems-parserState.genericsElems>0){throw["Cannot use literal search when there is more than one element"]}parserState.pos+=1;const start=parserState.pos;const end=getIdentEndPosition(parserState);if(parserState.pos>=parserState.length){throw["Unclosed ","\""]}else if(parserState.userQuery[end]!=="\""){throw["Unexpected ",parserState.userQuery[end]," in a string element"]}else if(start===end){throw["Cannot have empty string element"]}parserState.pos+=1;query.literalSearch=true}function isPathStart(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="::"}function isReturnArrow(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="->"}function isIdentCharacter(c){return(c==="_"||(c>="0"&&c<="9")||(c>="a"&&c<="z")||(c>="A"&&c<="Z"))}function isSeparatorCharacter(c){return c===","||c==="="}function isPathSeparator(c){return c===":"||c===" "}function prevIs(parserState,lookingFor){let pos=parserState.pos;while(pos>0){const c=parserState.userQuery[pos-1];if(c===lookingFor){return true}else if(c!==" "){break}pos-=1}return false}function isLastElemGeneric(elems,parserState){return(elems.length>0&&elems[elems.length-1].generics.length>0)||prevIs(parserState,">")}function skipWhitespace(parserState){while(parserState.pos0){throw["Cannot have more than one element if you use quotes"]}const typeFilter=parserState.typeFilter;parserState.typeFilter=null;if(name==="!"){if(typeFilter!==null&&typeFilter!=="primitive"){throw["Invalid search type: primitive never type ","!"," and ",typeFilter," both specified",]}if(generics.length!==0){throw["Never type ","!"," does not accept generic parameters",]}const bindingName=parserState.isInBinding;parserState.isInBinding=null;return{name:"never",id:null,fullPath:["never"],pathWithoutLast:[],pathLast:"never",normalizedPathLast:"never",generics:[],bindings:new Map(),typeFilter:"primitive",bindingName,}}const quadcolon=/::\s*::/.exec(path);if(path.startsWith("::")){throw["Paths cannot start with ","::"]}else if(path.endsWith("::")){throw["Paths cannot end with ","::"]}else if(quadcolon!==null){throw["Unexpected ",quadcolon[0]]}const pathSegments=path.split(/(?:::\s*)|(?:\s+(?:::\s*)?)/);if(pathSegments.length===0||(pathSegments.length===1&&pathSegments[0]==="")){if(generics.length>0||prevIs(parserState,">")){throw["Found generics without a path"]}else{throw["Unexpected ",parserState.userQuery[parserState.pos]]}}for(const[i,pathSegment]of pathSegments.entries()){if(pathSegment==="!"){if(i!==0){throw["Never type ","!"," is not associated item"]}pathSegments[i]="never"}}parserState.totalElems+=1;if(isInGenerics){parserState.genericsElems+=1}const bindingName=parserState.isInBinding;parserState.isInBinding=null;const bindings=new Map();const pathLast=pathSegments[pathSegments.length-1];return{name:name.trim(),id:null,fullPath:pathSegments,pathWithoutLast:pathSegments.slice(0,pathSegments.length-1),pathLast,normalizedPathLast:pathLast.replace(/_/g,""),generics:generics.filter(gen=>{if(gen.bindingName!==null){bindings.set(gen.bindingName.name,[gen,...gen.bindingName.generics]);return false}return true}),bindings,typeFilter,bindingName,}}function getIdentEndPosition(parserState){const start=parserState.pos;let end=parserState.pos;let foundExclamation=-1;while(parserState.pos0){throw["Unexpected ",c," after ",parserState.userQuery[parserState.pos-1]]}else{throw["Unexpected ",c]}}parserState.pos+=1;end=parserState.pos}if(foundExclamation!==-1&&foundExclamation!==start&&isIdentCharacter(parserState.userQuery[foundExclamation-1])){if(parserState.typeFilter===null){parserState.typeFilter="macro"}else if(parserState.typeFilter!=="macro"){throw["Invalid search type: macro ","!"," and ",parserState.typeFilter," both specified",]}end=foundExclamation}return end}function getNextElem(query,parserState,elems,isInGenerics){const generics=[];skipWhitespace(parserState);let start=parserState.pos;let end;if("[(".indexOf(parserState.userQuery[parserState.pos])!==-1){let endChar=")";let name="()";let friendlyName="tuple";if(parserState.userQuery[parserState.pos]==="["){endChar="]";name="[]";friendlyName="slice"}parserState.pos+=1;const{foundSeparator}=getItemsBefore(query,parserState,generics,endChar);const typeFilter=parserState.typeFilter;const isInBinding=parserState.isInBinding;if(typeFilter!==null&&typeFilter!=="primitive"){throw["Invalid search type: primitive ",name," and ",typeFilter," both specified",]}parserState.typeFilter=null;parserState.isInBinding=null;for(const gen of generics){if(gen.bindingName!==null){throw["Type parameter ","=",` cannot be within ${friendlyName} `,name]}}if(name==="()"&&!foundSeparator&&generics.length===1&&typeFilter===null){elems.push(generics[0])}else{parserState.totalElems+=1;if(isInGenerics){parserState.genericsElems+=1}elems.push({name:name,id:null,fullPath:[name],pathWithoutLast:[],pathLast:name,normalizedPathLast:name,generics,bindings:new Map(),typeFilter:"primitive",bindingName:isInBinding,})}}else{const isStringElem=parserState.userQuery[start]==="\"";if(isStringElem){start+=1;getStringElem(query,parserState,isInGenerics);end=parserState.pos-1}else{end=getIdentEndPosition(parserState)}if(parserState.pos=end){throw["Found generics without a path"]}parserState.pos+=1;getItemsBefore(query,parserState,generics,">")}if(isStringElem){skipWhitespace(parserState)}if(start>=end&&generics.length===0){return}if(parserState.userQuery[parserState.pos]==="="){if(parserState.isInBinding){throw["Cannot write ","="," twice in a binding"]}if(!isInGenerics){throw["Type parameter ","="," must be within generics list"]}const name=parserState.userQuery.slice(start,end).trim();if(name==="!"){throw["Type parameter ","="," key cannot be ","!"," never type"]}if(name.includes("!")){throw["Type parameter ","="," key cannot be ","!"," macro"]}if(name.includes("::")){throw["Type parameter ","="," key cannot contain ","::"," path"]}if(name.includes(":")){throw["Type parameter ","="," key cannot contain ",":"," type"]}parserState.isInBinding={name,generics}}else{elems.push(createQueryElement(query,parserState,parserState.userQuery.slice(start,end),generics,isInGenerics))}}}function getItemsBefore(query,parserState,elems,endChar){let foundStopChar=true;let foundSeparator=false;let start=parserState.pos;const oldTypeFilter=parserState.typeFilter;parserState.typeFilter=null;const oldIsInBinding=parserState.isInBinding;parserState.isInBinding=null;let extra="";if(endChar===">"){extra="<"}else if(endChar==="]"){extra="["}else if(endChar===")"){extra="("}else if(endChar===""){extra="->"}else{extra=endChar}while(parserState.pos"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(endChar!==""){throw["Expected ",",",", ","=",", or ",endChar,...extra,", found ",c,]}throw["Expected ",","," or ","=",...extra,", found ",c,]}const posBefore=parserState.pos;start=parserState.pos;getNextElem(query,parserState,elems,endChar!=="");if(endChar!==""&&parserState.pos>=parserState.length){throw["Unclosed ",extra]}if(posBefore===parserState.pos){parserState.pos+=1}foundStopChar=false}if(parserState.pos>=parserState.length&&endChar!==""){throw["Unclosed ",extra]}parserState.pos+=1;parserState.typeFilter=oldTypeFilter;parserState.isInBinding=oldIsInBinding;return{foundSeparator}}function checkExtraTypeFilterCharacters(start,parserState){const query=parserState.userQuery.slice(start,parserState.pos).trim();for(const c in query){if(!isIdentCharacter(query[c])){throw["Unexpected ",query[c]," in type filter (before ",":",")",]}}}function parseInput(query,parserState){let foundStopChar=true;let start=parserState.pos;while(parserState.pos"){if(isReturnArrow(parserState)){break}throw["Unexpected ",c," (did you mean ","->","?)"]}else if(parserState.pos>0){throw["Unexpected ",c," after ",parserState.userQuery[parserState.pos-1]]}throw["Unexpected ",c]}else if(c===":"&&!isPathStart(parserState)){if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}else if(query.elems.length===0){throw["Expected type filter before ",":"]}else if(query.literalSearch){throw["Cannot use quotes on type filter"]}const typeFilterElem=query.elems.pop();checkExtraTypeFilterCharacters(start,parserState);parserState.typeFilter=typeFilterElem.name;parserState.pos+=1;parserState.totalElems-=1;query.literalSearch=false;foundStopChar=true;continue}else if(c===" "){skipWhitespace(parserState);continue}if(!foundStopChar){let extra="";if(isLastElemGeneric(query.elems,parserState)){extra=[" after ",">"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(parserState.typeFilter!==null){throw["Expected ",","," or ","->",...extra,", found ",c,]}throw["Expected ",",",", ",":"," or ","->",...extra,", found ",c,]}const before=query.elems.length;start=parserState.pos;getNextElem(query,parserState,query.elems,false);if(query.elems.length===before){parserState.pos+=1}foundStopChar=false}if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}while(parserState.pos"]}break}else{parserState.pos+=1}}}function newParsedQuery(userQuery){return{original:userQuery,userQuery:userQuery.toLowerCase(),elems:[],returned:[],foundElems:0,totalElems:0,literalSearch:false,error:null,correction:null,proposeCorrectionFrom:null,proposeCorrectionTo:null,typeFingerprint:new Uint32Array(4),}}function buildUrl(search,filterCrates){let extra="?search="+encodeURIComponent(search);if(filterCrates!==null){extra+="&filter-crate="+encodeURIComponent(filterCrates)}return getNakedUrl()+extra+window.location.hash}function getFilterCrates(){const elem=document.getElementById("crate-search");if(elem&&elem.value!=="all crates"&&rawSearchIndex.has(elem.value)){return elem.value}return null}function parseQuery(userQuery){function convertTypeFilterOnElem(elem){if(elem.typeFilter!==null){let typeFilter=elem.typeFilter;if(typeFilter==="const"){typeFilter="constant"}elem.typeFilter=itemTypeFromName(typeFilter)}else{elem.typeFilter=NO_TYPE_FILTER}for(const elem2 of elem.generics){convertTypeFilterOnElem(elem2)}for(const constraints of elem.bindings.values()){for(const constraint of constraints){convertTypeFilterOnElem(constraint)}}}userQuery=userQuery.trim().replace(/\r|\n|\t/g," ");const parserState={length:userQuery.length,pos:0,totalElems:0,genericsElems:0,typeFilter:null,isInBinding:null,userQuery:userQuery.toLowerCase(),};let query=newParsedQuery(userQuery);try{parseInput(query,parserState);for(const elem of query.elems){convertTypeFilterOnElem(elem)}for(const elem of query.returned){convertTypeFilterOnElem(elem)}}catch(err){query=newParsedQuery(userQuery);query.error=err;return query}if(!query.literalSearch){query.literalSearch=parserState.totalElems>1}query.foundElems=query.elems.length+query.returned.length;query.totalElems=parserState.totalElems;return query}function createQueryResults(results_in_args,results_returned,results_others,parsedQuery){return{"in_args":results_in_args,"returned":results_returned,"others":results_others,"query":parsedQuery,}}function execQuery(parsedQuery,filterCrates,currentCrate){const results_others=new Map(),results_in_args=new Map(),results_returned=new Map();function transformResults(results){const duplicates=new Set();const out=[];for(const result of results){if(result.id!==-1){const obj=searchIndex[result.id];obj.dist=result.dist;const res=buildHrefAndPath(obj);obj.displayPath=pathSplitter(res[0]);obj.fullPath=obj.displayPath+obj.name;obj.fullPath+="|"+obj.ty;if(duplicates.has(obj.fullPath)){continue}duplicates.add(obj.fullPath);obj.href=res[1];out.push(obj);if(out.length>=MAX_RESULTS){break}}}return out}function sortResults(results,isType,preferredCrate){if(results.size===0){return[]}const userQuery=parsedQuery.userQuery;const result_list=[];for(const result of results.values()){result.item=searchIndex[result.id];result.word=searchIndex[result.id].word;result_list.push(result)}result_list.sort((aaa,bbb)=>{let a,b;a=(aaa.word!==userQuery);b=(bbb.word!==userQuery);if(a!==b){return a-b}a=(aaa.index<0);b=(bbb.index<0);if(a!==b){return a-b}a=aaa.path_dist;b=bbb.path_dist;if(a!==b){return a-b}a=aaa.index;b=bbb.index;if(a!==b){return a-b}a=(aaa.dist);b=(bbb.dist);if(a!==b){return a-b}a=aaa.item.deprecated;b=bbb.item.deprecated;if(a!==b){return a-b}a=(aaa.item.crate!==preferredCrate);b=(bbb.item.crate!==preferredCrate);if(a!==b){return a-b}a=aaa.word.length;b=bbb.word.length;if(a!==b){return a-b}a=aaa.word;b=bbb.word;if(a!==b){return(a>b?+1:-1)}a=(aaa.item.desc==="");b=(bbb.item.desc==="");if(a!==b){return a-b}a=aaa.item.ty;b=bbb.item.ty;if(a!==b){return a-b}a=aaa.item.path;b=bbb.item.path;if(a!==b){return(a>b?+1:-1)}return 0});return transformResults(result_list)}function unifyFunctionTypes(fnTypesIn,queryElems,whereClause,mgensIn,solutionCb){const mgens=mgensIn===null?null:new Map(mgensIn);if(queryElems.length===0){return!solutionCb||solutionCb(mgens)}if(!fnTypesIn||fnTypesIn.length===0){return false}const ql=queryElems.length;const fl=fnTypesIn.length;if(ql===1&&queryElems[0].generics.length===0&&queryElems[0].bindings.size===0){const queryElem=queryElems[0];for(const fnType of fnTypesIn){if(!unifyFunctionTypeIsMatchCandidate(fnType,queryElem,whereClause,mgens)){continue}if(fnType.id<0&&queryElem.id<0){if(mgens&&mgens.has(fnType.id)&&mgens.get(fnType.id)!==queryElem.id){continue}const mgensScratch=new Map(mgens);mgensScratch.set(fnType.id,queryElem.id);if(!solutionCb||solutionCb(mgensScratch)){return true}}else if(!solutionCb||solutionCb(mgens?new Map(mgens):null)){return true}}for(const fnType of fnTypesIn){if(!unifyFunctionTypeIsUnboxCandidate(fnType,queryElem,whereClause,mgens)){continue}if(fnType.id<0){if(mgens&&mgens.has(fnType.id)&&mgens.get(fnType.id)!==0){continue}const mgensScratch=new Map(mgens);mgensScratch.set(fnType.id,0);if(unifyFunctionTypes(whereClause[(-fnType.id)-1],queryElems,whereClause,mgensScratch,solutionCb)){return true}}else if(unifyFunctionTypes([...fnType.generics,...Array.from(fnType.bindings.values()).flat()],queryElems,whereClause,mgens?new Map(mgens):null,solutionCb)){return true}}return false}const fnTypes=fnTypesIn.slice();const flast=fl-1;const qlast=ql-1;const queryElem=queryElems[qlast];let queryElemsTmp=null;for(let i=flast;i>=0;i-=1){const fnType=fnTypes[i];if(!unifyFunctionTypeIsMatchCandidate(fnType,queryElem,whereClause,mgens)){continue}let mgensScratch;if(fnType.id<0){mgensScratch=new Map(mgens);if(mgensScratch.has(fnType.id)&&mgensScratch.get(fnType.id)!==queryElem.id){continue}mgensScratch.set(fnType.id,queryElem.id)}else{mgensScratch=mgens}fnTypes[i]=fnTypes[flast];fnTypes.length=flast;if(!queryElemsTmp){queryElemsTmp=queryElems.slice(0,qlast)}const passesUnification=unifyFunctionTypes(fnTypes,queryElemsTmp,whereClause,mgensScratch,mgensScratch=>{if(fnType.generics.length===0&&queryElem.generics.length===0&&fnType.bindings.size===0&&queryElem.bindings.size===0){return!solutionCb||solutionCb(mgensScratch)}const solution=unifyFunctionTypeCheckBindings(fnType,queryElem,whereClause,mgensScratch);if(!solution){return false}const simplifiedGenerics=solution.simplifiedGenerics;for(const simplifiedMgens of solution.mgens){const passesUnification=unifyFunctionTypes(simplifiedGenerics,queryElem.generics,whereClause,simplifiedMgens,solutionCb);if(passesUnification){return true}}return false});if(passesUnification){return true}fnTypes[flast]=fnTypes[i];fnTypes[i]=fnType;fnTypes.length=fl}for(let i=flast;i>=0;i-=1){const fnType=fnTypes[i];if(!unifyFunctionTypeIsUnboxCandidate(fnType,queryElem,whereClause,mgens)){continue}let mgensScratch;if(fnType.id<0){mgensScratch=new Map(mgens);if(mgensScratch.has(fnType.id)&&mgensScratch.get(fnType.id)!==0){continue}mgensScratch.set(fnType.id,0)}else{mgensScratch=mgens}const generics=fnType.id<0?whereClause[(-fnType.id)-1]:fnType.generics;const bindings=fnType.bindings?Array.from(fnType.bindings.values()).flat():[];const passesUnification=unifyFunctionTypes(fnTypes.toSpliced(i,1,...generics,...bindings),queryElems,whereClause,mgensScratch,solutionCb);if(passesUnification){return true}}return false}function unifyFunctionTypeIsMatchCandidate(fnType,queryElem,whereClause,mgensIn){if(!typePassesFilter(queryElem.typeFilter,fnType.ty)){return false}if(fnType.id<0&&queryElem.id<0){if(mgensIn){if(mgensIn.has(fnType.id)&&mgensIn.get(fnType.id)!==queryElem.id){return false}for(const[fid,qid]of mgensIn.entries()){if(fnType.id!==fid&&queryElem.id===qid){return false}if(fnType.id===fid&&queryElem.id!==qid){return false}}}return true}else{if(queryElem.id===typeNameIdOfArrayOrSlice&&(fnType.id===typeNameIdOfSlice||fnType.id===typeNameIdOfArray)){}else if(queryElem.id===typeNameIdOfTupleOrUnit&&(fnType.id===typeNameIdOfTuple||fnType.id===typeNameIdOfUnit)){}else if(fnType.id!==queryElem.id||queryElem.id===null){return false}if((fnType.generics.length+fnType.bindings.size)===0&&queryElem.generics.length!==0){return false}if(fnType.bindings.size0){const fnTypePath=fnType.path!==undefined&&fnType.path!==null?fnType.path.split("::"):[];if(queryElemPathLength>fnTypePath.length){return false}let i=0;for(const path of fnTypePath){if(path===queryElem.pathWithoutLast[i]){i+=1;if(i>=queryElemPathLength){break}}}if(i0){let mgensSolutionSet=[mgensIn];for(const[name,constraints]of queryElem.bindings.entries()){if(mgensSolutionSet.length===0){return false}if(!fnType.bindings.has(name)){return false}const fnTypeBindings=fnType.bindings.get(name);mgensSolutionSet=mgensSolutionSet.flatMap(mgens=>{const newSolutions=[];unifyFunctionTypes(fnTypeBindings,constraints,whereClause,mgens,newMgens=>{newSolutions.push(newMgens);return false});return newSolutions})}if(mgensSolutionSet.length===0){return false}const binds=Array.from(fnType.bindings.entries()).flatMap(entry=>{const[name,constraints]=entry;if(queryElem.bindings.has(name)){return[]}else{return constraints}});if(simplifiedGenerics.length>0){simplifiedGenerics=[...simplifiedGenerics,...binds]}else{simplifiedGenerics=binds}return{simplifiedGenerics,mgens:mgensSolutionSet}}return{simplifiedGenerics,mgens:[mgensIn]}}function unifyFunctionTypeIsUnboxCandidate(fnType,queryElem,whereClause,mgens){if(fnType.id<0&&queryElem.id>=0){if(!whereClause){return false}if(mgens&&mgens.has(fnType.id)&&mgens.get(fnType.id)!==0){return false}const mgensTmp=new Map(mgens);mgensTmp.set(fnType.id,null);return checkIfInList(whereClause[(-fnType.id)-1],queryElem,whereClause,mgensTmp)}else if(fnType.generics.length>0||fnType.bindings.size>0){const simplifiedGenerics=[...fnType.generics,...Array.from(fnType.bindings.values()).flat(),];return checkIfInList(simplifiedGenerics,queryElem,whereClause,mgens)}return false}function checkIfInList(list,elem,whereClause,mgens){for(const entry of list){if(checkType(entry,elem,whereClause,mgens)){return true}}return false}function checkType(row,elem,whereClause,mgens){if(row.bindings.size===0&&elem.bindings.size===0){if(elem.id<0){return row.id<0||checkIfInList(row.generics,elem,whereClause,mgens)}if(row.id>0&&elem.id>0&&elem.pathWithoutLast.length===0&&typePassesFilter(elem.typeFilter,row.ty)&&elem.generics.length===0&&elem.id!==typeNameIdOfArrayOrSlice&&elem.id!==typeNameIdOfTupleOrUnit){return row.id===elem.id||checkIfInList(row.generics,elem,whereClause,mgens)}}return unifyFunctionTypes([row],[elem],whereClause,mgens)}function checkPath(contains,ty){if(contains.length===0){return 0}const maxPathEditDistance=Math.floor(contains.reduce((acc,next)=>acc+next.length,0)/3);let ret_dist=maxPathEditDistance+1;const path=ty.path.split("::");if(ty.parent&&ty.parent.name){path.push(ty.parent.name.toLowerCase())}const length=path.length;const clength=contains.length;pathiter:for(let i=length-clength;i>=0;i-=1){let dist_total=0;for(let x=0;xmaxPathEditDistance){continue pathiter}dist_total+=dist}}ret_dist=Math.min(ret_dist,Math.round(dist_total/clength))}return ret_dist>maxPathEditDistance?null:ret_dist}function typePassesFilter(filter,type){if(filter<=NO_TYPE_FILTER||filter===type)return true;const name=itemTypes[type];switch(itemTypes[filter]){case"constant":return name==="associatedconstant";case"fn":return name==="method"||name==="tymethod";case"type":return name==="primitive"||name==="associatedtype";case"trait":return name==="traitalias"}return false}function createAliasFromItem(item){return{crate:item.crate,name:item.name,path:item.path,desc:item.desc,ty:item.ty,parent:item.parent,type:item.type,is_alias:true,deprecated:item.deprecated,implDisambiguator:item.implDisambiguator,}}function handleAliases(ret,query,filterCrates,currentCrate){const lowerQuery=query.toLowerCase();const aliases=[];const crateAliases=[];if(filterCrates!==null){if(ALIASES.has(filterCrates)&&ALIASES.get(filterCrates).has(lowerQuery)){const query_aliases=ALIASES.get(filterCrates).get(lowerQuery);for(const alias of query_aliases){aliases.push(createAliasFromItem(searchIndex[alias]))}}}else{for(const[crate,crateAliasesIndex]of ALIASES){if(crateAliasesIndex.has(lowerQuery)){const pushTo=crate===currentCrate?crateAliases:aliases;const query_aliases=crateAliasesIndex.get(lowerQuery);for(const alias of query_aliases){pushTo.push(createAliasFromItem(searchIndex[alias]))}}}}const sortFunc=(aaa,bbb)=>{if(aaa.path{alias.alias=query;const res=buildHrefAndPath(alias);alias.displayPath=pathSplitter(res[0]);alias.fullPath=alias.displayPath+alias.name;alias.href=res[1];ret.others.unshift(alias);if(ret.others.length>MAX_RESULTS){ret.others.pop()}};aliases.forEach(pushFunc);crateAliases.forEach(pushFunc)}function addIntoResults(results,fullId,id,index,dist,path_dist,maxEditDistance){if(dist<=maxEditDistance||index!==-1){if(results.has(fullId)){const result=results.get(fullId);if(result.dontValidate||result.dist<=dist){return}}results.set(fullId,{id:id,index:index,dontValidate:parsedQuery.literalSearch,dist:dist,path_dist:path_dist,})}}function handleSingleArg(row,pos,elem,results_others,results_in_args,results_returned,maxEditDistance){if(!row||(filterCrates!==null&&row.crate!==filterCrates)){return}let path_dist=0;const fullId=row.id;const tfpDist=compareTypeFingerprints(fullId,parsedQuery.typeFingerprint);if(tfpDist!==null){const in_args=row.type&&row.type.inputs&&checkIfInList(row.type.inputs,elem,row.type.where_clause);const returned=row.type&&row.type.output&&checkIfInList(row.type.output,elem,row.type.where_clause);if(in_args){results_in_args.max_dist=Math.max(results_in_args.max_dist||0,tfpDist);const maxDist=results_in_args.sizenormalizedIndex&&normalizedIndex!==-1)){index=normalizedIndex}if(elem.fullPath.length>1){path_dist=checkPath(elem.pathWithoutLast,row);if(path_dist===null){return}}if(parsedQuery.literalSearch){if(row.word===elem.pathLast){addIntoResults(results_others,fullId,pos,index,0,path_dist)}return}const dist=editDistance(row.normalizedName,elem.normalizedPathLast,maxEditDistance);if(index===-1&&dist>maxEditDistance){return}addIntoResults(results_others,fullId,pos,index,dist,path_dist,maxEditDistance)}function handleArgs(row,pos,results){if(!row||(filterCrates!==null&&row.crate!==filterCrates)||!row.type){return}const tfpDist=compareTypeFingerprints(row.id,parsedQuery.typeFingerprint);if(tfpDist===null){return}if(results.size>=MAX_RESULTS&&tfpDist>results.max_dist){return}if(!unifyFunctionTypes(row.type.inputs,parsedQuery.elems,row.type.where_clause,null,mgens=>{return unifyFunctionTypes(row.type.output,parsedQuery.returned,row.type.where_clause,mgens)})){return}results.max_dist=Math.max(results.max_dist||0,tfpDist);addIntoResults(results,row.id,pos,0,tfpDist,0,Number.MAX_VALUE)}function innerRunQuery(){const queryLen=parsedQuery.elems.reduce((acc,next)=>acc+next.pathLast.length,0)+parsedQuery.returned.reduce((acc,next)=>acc+next.pathLast.length,0);const maxEditDistance=Math.floor(queryLen/3);const genericSymbols=new Map();function convertNameToId(elem,isAssocType){if(typeNameIdMap.has(elem.normalizedPathLast)&&(isAssocType||!typeNameIdMap.get(elem.normalizedPathLast).assocOnly)){elem.id=typeNameIdMap.get(elem.normalizedPathLast).id}else if(!parsedQuery.literalSearch){let match=null;let matchDist=maxEditDistance+1;let matchName="";for(const[name,{id,assocOnly}]of typeNameIdMap){const dist=editDistance(name,elem.normalizedPathLast,maxEditDistance);if(dist<=matchDist&&dist<=maxEditDistance&&(isAssocType||!assocOnly)){if(dist===matchDist&&matchName>name){continue}match=id;matchDist=dist;matchName=name}}if(match!==null){parsedQuery.correction=matchName}elem.id=match}if((elem.id===null&&parsedQuery.totalElems>1&&elem.typeFilter===-1&&elem.generics.length===0&&elem.bindings.size===0)||elem.typeFilter===TY_GENERIC){if(genericSymbols.has(elem.name)){elem.id=genericSymbols.get(elem.name)}else{elem.id=-(genericSymbols.size+1);genericSymbols.set(elem.name,elem.id)}if(elem.typeFilter===-1&&elem.name.length>=3){const maxPartDistance=Math.floor(elem.name.length/3);let matchDist=maxPartDistance+1;let matchName="";for(const name of typeNameIdMap.keys()){const dist=editDistance(name,elem.name,maxPartDistance);if(dist<=matchDist&&dist<=maxPartDistance){if(dist===matchDist&&matchName>name){continue}matchDist=dist;matchName=name}}if(matchName!==""){parsedQuery.proposeCorrectionFrom=elem.name;parsedQuery.proposeCorrectionTo=matchName}}elem.typeFilter=TY_GENERIC}if(elem.generics.length>0&&elem.typeFilter===TY_GENERIC){parsedQuery.error=["Generic type parameter ",elem.name," does not accept generic parameters",]}for(const elem2 of elem.generics){convertNameToId(elem2)}elem.bindings=new Map(Array.from(elem.bindings.entries()).map(entry=>{const[name,constraints]=entry;if(!typeNameIdMap.has(name)){parsedQuery.error=["Type parameter ",name," does not exist",];return[null,[]]}for(const elem2 of constraints){convertNameToId(elem2)}return[typeNameIdMap.get(name).id,constraints]}))}const fps=new Set();for(const elem of parsedQuery.elems){convertNameToId(elem);buildFunctionTypeFingerprint(elem,parsedQuery.typeFingerprint,fps)}for(const elem of parsedQuery.returned){convertNameToId(elem);buildFunctionTypeFingerprint(elem,parsedQuery.typeFingerprint,fps)}if(parsedQuery.foundElems===1&&parsedQuery.returned.length===0){if(parsedQuery.elems.length===1){const elem=parsedQuery.elems[0];for(let i=0,nSearchIndex=searchIndex.length;i0){const sortQ=(a,b)=>{const ag=a.generics.length===0&&a.bindings.size===0;const bg=b.generics.length===0&&b.bindings.size===0;if(ag!==bg){return ag-bg}const ai=a.id>0;const bi=b.id>0;return ai-bi};parsedQuery.elems.sort(sortQ);parsedQuery.returned.sort(sortQ);for(let i=0,nSearchIndex=searchIndex.length;i");if(tmp.endsWith("")){return tmp.slice(0,tmp.length-6)}return tmp}function addTab(array,query,display){const extraClass=display?" active":"";const output=document.createElement("div");if(array.length>0){output.className="search-results "+extraClass;array.forEach(item=>{const name=item.name;const type=itemTypes[item.ty];const longType=longItemTypes[item.ty];const typeName=longType.length!==0?`${longType}`:"?";const link=document.createElement("a");link.className="result-"+type;link.href=item.href;const resultName=document.createElement("div");resultName.className="result-name";resultName.insertAdjacentHTML("beforeend",`${typeName}`);link.appendChild(resultName);let alias=" ";if(item.is_alias){alias=`
    \ +${item.alias} - see \ +
    `}resultName.insertAdjacentHTML("beforeend",`
    ${alias}\ +${item.displayPath}${name}\ +
    `);const description=document.createElement("div");description.className="desc";description.insertAdjacentHTML("beforeend",item.desc);link.appendChild(description);output.appendChild(link)})}else if(query.error===null){output.className="search-failed"+extraClass;output.innerHTML="No results :(
    "+"Try on DuckDuckGo?

    "+"Or try looking in one of these:"}return[output,array.length]}function makeTabHeader(tabNb,text,nbElems){const fmtNbElems=nbElems<10?`\u{2007}(${nbElems})\u{2007}\u{2007}`:nbElems<100?`\u{2007}(${nbElems})\u{2007}`:`\u{2007}(${nbElems})`;if(searchState.currentTab===tabNb){return""}return""}function showResults(results,go_to_first,filterCrates){const search=searchState.outputElement();if(go_to_first||(results.others.length===1&&getSettingValue("go-to-only-result")==="true")){window.onunload=()=>{};searchState.removeQueryParameters();const elem=document.createElement("a");elem.href=results.others[0].href;removeClass(elem,"active");document.body.appendChild(elem);elem.click();return}if(results.query===undefined){results.query=parseQuery(searchState.input.value)}currentResults=results.query.userQuery;const ret_others=addTab(results.others,results.query,true);const ret_in_args=addTab(results.in_args,results.query,false);const ret_returned=addTab(results.returned,results.query,false);let currentTab=searchState.currentTab;if((currentTab===0&&ret_others[1]===0)||(currentTab===1&&ret_in_args[1]===0)||(currentTab===2&&ret_returned[1]===0)){if(ret_others[1]!==0){currentTab=0}else if(ret_in_args[1]!==0){currentTab=1}else if(ret_returned[1]!==0){currentTab=2}}let crates="";if(rawSearchIndex.size>1){crates=" in 
    "}let output=`

    Results${crates}

    `;if(results.query.error!==null){const error=results.query.error;error.forEach((value,index)=>{value=value.split("<").join("<").split(">").join(">");if(index%2!==0){error[index]=`${value.replaceAll(" ", " ")}`}else{error[index]=value}});output+=`

    Query parser error: "${error.join("")}".

    `;output+="
    "+makeTabHeader(0,"In Names",ret_others[1])+"
    ";currentTab=0}else if(results.query.foundElems<=1&&results.query.returned.length===0){output+="
    "+makeTabHeader(0,"In Names",ret_others[1])+makeTabHeader(1,"In Parameters",ret_in_args[1])+makeTabHeader(2,"In Return Types",ret_returned[1])+"
    "}else{const signatureTabTitle=results.query.elems.length===0?"In Function Return Types":results.query.returned.length===0?"In Function Parameters":"In Function Signatures";output+="
    "+makeTabHeader(0,signatureTabTitle,ret_others[1])+"
    ";currentTab=0}if(results.query.correction!==null){const orig=results.query.returned.length>0?results.query.returned[0].name:results.query.elems[0].name;output+="

    "+`Type "${orig}" not found. `+"Showing results for closest type name "+`"${results.query.correction}" instead.

    `}if(results.query.proposeCorrectionFrom!==null){const orig=results.query.proposeCorrectionFrom;const targ=results.query.proposeCorrectionTo;output+="

    "+`Type "${orig}" not found and used as generic parameter. `+`Consider searching for "${targ}" instead.

    `}const resultsElem=document.createElement("div");resultsElem.id="results";resultsElem.appendChild(ret_others[0]);resultsElem.appendChild(ret_in_args[0]);resultsElem.appendChild(ret_returned[0]);search.innerHTML=output;const crateSearch=document.getElementById("crate-search");if(crateSearch){crateSearch.addEventListener("input",updateCrate)}search.appendChild(resultsElem);searchState.showResults(search);const elems=document.getElementById("search-tabs").childNodes;searchState.focusedByTab=[];let i=0;for(const elem of elems){const j=i;elem.onclick=()=>printTab(j);searchState.focusedByTab.push(null);i+=1}printTab(currentTab)}function updateSearchHistory(url){if(!browserSupportsHistoryApi()){return}const params=searchState.getQueryStringParams();if(!history.state&&!params.search){history.pushState(null,"",url)}else{history.replaceState(null,"",url)}}function search(forced){const query=parseQuery(searchState.input.value.trim());let filterCrates=getFilterCrates();if(!forced&&query.userQuery===currentResults){if(query.userQuery.length>0){putBackSearch()}return}searchState.setLoadingSearch();const params=searchState.getQueryStringParams();if(filterCrates===null&¶ms["filter-crate"]!==undefined){filterCrates=params["filter-crate"]}searchState.title="Results for "+query.original+" - Rust";updateSearchHistory(buildUrl(query.original,filterCrates));showResults(execQuery(query,filterCrates,window.currentCrate),params.go_to_first,filterCrates)}function buildItemSearchTypeAll(types,lowercasePaths){return types.length>0?types.map(type=>buildItemSearchType(type,lowercasePaths)):EMPTY_GENERICS_ARRAY}const EMPTY_BINDINGS_MAP=new Map();const EMPTY_GENERICS_ARRAY=[];let TYPES_POOL=new Map();function buildItemSearchType(type,lowercasePaths,isAssocType){const PATH_INDEX_DATA=0;const GENERICS_DATA=1;const BINDINGS_DATA=2;let pathIndex,generics,bindings;if(typeof type==="number"){pathIndex=type;generics=EMPTY_GENERICS_ARRAY;bindings=EMPTY_BINDINGS_MAP}else{pathIndex=type[PATH_INDEX_DATA];generics=buildItemSearchTypeAll(type[GENERICS_DATA],lowercasePaths);if(type.length>BINDINGS_DATA&&type[BINDINGS_DATA].length>0){bindings=new Map(type[BINDINGS_DATA].map(binding=>{const[assocType,constraints]=binding;return[buildItemSearchType(assocType,lowercasePaths,true).id,buildItemSearchTypeAll(constraints,lowercasePaths),]}))}else{bindings=EMPTY_BINDINGS_MAP}}let result;if(pathIndex<0){result={id:pathIndex,ty:TY_GENERIC,path:null,generics,bindings,}}else if(pathIndex===0){result={id:null,ty:null,path:null,generics,bindings,}}else{const item=lowercasePaths[pathIndex-1];result={id:buildTypeMapIndex(item.name,isAssocType),ty:item.ty,path:item.path,generics,bindings,}}const cr=TYPES_POOL.get(result.id);if(cr){if(cr.generics.length===result.generics.length&&cr.generics!==result.generics&&cr.generics.every((x,i)=>result.generics[i]===x)){result.generics=cr.generics}if(cr.bindings.size===result.bindings.size&&cr.bindings!==result.bindings){let ok=true;for(const[k,v]of cr.bindings.entries()){const v2=result.bindings.get(v);if(!v2){ok=false;break}if(v!==v2&&v.length===v2.length&&v.every((x,i)=>v2[i]===x)){result.bindings.set(k,v)}else if(v!==v2){ok=false;break}}if(ok){result.bindings=cr.bindings}}if(cr.ty===result.ty&&cr.path===result.path&&cr.bindings===result.bindings&&cr.generics===result.generics&&cr.ty===result.ty){return cr}}TYPES_POOL.set(result.id,result);return result}function buildFunctionSearchType(itemFunctionDecoder,lowercasePaths){const c=itemFunctionDecoder.string.charCodeAt(itemFunctionDecoder.offset);itemFunctionDecoder.offset+=1;const[zero,ua,la,ob,cb]=["0","@","`","{","}"].map(c=>c.charCodeAt(0));if(c===la){return null}if(c>=zero&&c>1];itemFunctionDecoder.offset+=1;return sign?-value:value}const functionSearchType=decodeList();const INPUTS_DATA=0;const OUTPUT_DATA=1;let inputs,output;if(typeof functionSearchType[INPUTS_DATA]==="number"){inputs=[buildItemSearchType(functionSearchType[INPUTS_DATA],lowercasePaths)]}else{inputs=buildItemSearchTypeAll(functionSearchType[INPUTS_DATA],lowercasePaths)}if(functionSearchType.length>1){if(typeof functionSearchType[OUTPUT_DATA]==="number"){output=[buildItemSearchType(functionSearchType[OUTPUT_DATA],lowercasePaths)]}else{output=buildItemSearchTypeAll(functionSearchType[OUTPUT_DATA],lowercasePaths)}}else{output=[]}const where_clause=[];const l=functionSearchType.length;for(let i=2;i16){itemFunctionDecoder.backrefQueue.pop()}return ret}function buildFunctionTypeFingerprint(type,output,fps){let input=type.id;if(input===typeNameIdOfArray||input===typeNameIdOfSlice){input=typeNameIdOfArrayOrSlice}if(input===typeNameIdOfTuple||input===typeNameIdOfUnit){input=typeNameIdOfTupleOrUnit}const hashint1=k=>{k=(~~k+0x7ed55d16)+(k<<12);k=(k ^ 0xc761c23c)^(k>>>19);k=(~~k+0x165667b1)+(k<<5);k=(~~k+0xd3a2646c)^(k<<9);k=(~~k+0xfd7046c5)+(k<<3);return(k ^ 0xb55a4f09)^(k>>>16)};const hashint2=k=>{k=~k+(k<<15);k ^=k>>>12;k+=k<<2;k ^=k>>>4;k=Math.imul(k,2057);return k ^(k>>16)};if(input!==null){const h0a=hashint1(input);const h0b=hashint2(input);const h1a=~~(h0a+Math.imul(h0b,2));const h1b=~~(h0a+Math.imul(h0b,3));const h2a=~~(h0a+Math.imul(h0b,4));const h2b=~~(h0a+Math.imul(h0b,5));output[0]|=(1<<(h0a%32))|(1<<(h1b%32));output[1]|=(1<<(h1a%32))|(1<<(h2b%32));output[2]|=(1<<(h2a%32))|(1<<(h0b%32));fps.add(input)}for(const g of type.generics){buildFunctionTypeFingerprint(g,output,fps)}const fb={id:null,ty:0,generics:EMPTY_GENERICS_ARRAY,bindings:EMPTY_BINDINGS_MAP,};for(const[k,v]of type.bindings.entries()){fb.id=k;fb.generics=v;buildFunctionTypeFingerprint(fb,output,fps)}output[3]=fps.size}function compareTypeFingerprints(fullId,queryFingerprint){const fh0=functionTypeFingerprint[fullId*4];const fh1=functionTypeFingerprint[(fullId*4)+1];const fh2=functionTypeFingerprint[(fullId*4)+2];const[qh0,qh1,qh2]=queryFingerprint;const[in0,in1,in2]=[fh0&qh0,fh1&qh1,fh2&qh2];if((in0 ^ qh0)||(in1 ^ qh1)||(in2 ^ qh2)){return null}return functionTypeFingerprint[(fullId*4)+3]}function buildIndex(rawSearchIndex){searchIndex=[];typeNameIdMap=new Map();const charA="A".charCodeAt(0);let currentIndex=0;let id=0;typeNameIdOfArray=buildTypeMapIndex("array");typeNameIdOfSlice=buildTypeMapIndex("slice");typeNameIdOfTuple=buildTypeMapIndex("tuple");typeNameIdOfUnit=buildTypeMapIndex("unit");typeNameIdOfArrayOrSlice=buildTypeMapIndex("[]");typeNameIdOfTupleOrUnit=buildTypeMapIndex("()");for(const crate of rawSearchIndex.values()){id+=crate.t.length+1}functionTypeFingerprint=new Uint32Array((id+1)*4);id=0;for(const[crate,crateCorpus]of rawSearchIndex){const crateRow={crate:crate,ty:3,name:crate,path:"",desc:crateCorpus.doc,parent:undefined,type:null,id:id,word:crate,normalizedName:crate.indexOf("_")===-1?crate:crate.replace(/_/g,""),deprecated:null,implDisambiguator:null,};id+=1;searchIndex.push(crateRow);currentIndex+=1;const itemTypes=crateCorpus.t;const itemNames=crateCorpus.n;const itemPaths=new Map(crateCorpus.q);const itemDescs=crateCorpus.d;const itemParentIdxs=crateCorpus.i;const itemFunctionDecoder={string:crateCorpus.f,offset:0,backrefQueue:[],};const deprecatedItems=new Set(crateCorpus.c);const implDisambiguator=new Map(crateCorpus.b);const paths=crateCorpus.p;const aliases=crateCorpus.a;const lowercasePaths=[];let len=paths.length;let lastPath=itemPaths.get(0);for(let i=0;i2){path=itemPaths.has(elem[2])?itemPaths.get(elem[2]):lastPath;lastPath=path}lowercasePaths.push({ty:ty,name:name.toLowerCase(),path:path});paths[i]={ty:ty,name:name,path:path}}lastPath="";len=itemTypes.length;for(let i=0;i0?paths[itemParentIdxs[i]-1]:undefined,type,id:id,word,normalizedName:word.indexOf("_")===-1?word:word.replace(/_/g,""),deprecated:deprecatedItems.has(i),implDisambiguator:implDisambiguator.has(i)?implDisambiguator.get(i):null,};id+=1;searchIndex.push(row);lastPath=row.path}if(aliases){const currentCrateAliases=new Map();ALIASES.set(crate,currentCrateAliases);for(const alias_name in aliases){if(!Object.prototype.hasOwnProperty.call(aliases,alias_name)){continue}let currentNameAliases;if(currentCrateAliases.has(alias_name)){currentNameAliases=currentCrateAliases.get(alias_name)}else{currentNameAliases=[];currentCrateAliases.set(alias_name,currentNameAliases)}for(const local_alias of aliases[alias_name]){currentNameAliases.push(local_alias+currentIndex)}}}currentIndex+=itemTypes.length}TYPES_POOL=new Map()}function onSearchSubmit(e){e.preventDefault();searchState.clearInputTimeout();search()}function putBackSearch(){const search_input=searchState.input;if(!searchState.input){return}if(search_input.value!==""&&!searchState.isDisplayed()){searchState.showResults();if(browserSupportsHistoryApi()){history.replaceState(null,"",buildUrl(search_input.value,getFilterCrates()))}document.title=searchState.title}}function registerSearchEvents(){const params=searchState.getQueryStringParams();if(searchState.input.value===""){searchState.input.value=params.search||""}const searchAfter500ms=()=>{searchState.clearInputTimeout();if(searchState.input.value.length===0){searchState.hideResults()}else{searchState.timeout=setTimeout(search,500)}};searchState.input.onkeyup=searchAfter500ms;searchState.input.oninput=searchAfter500ms;document.getElementsByClassName("search-form")[0].onsubmit=onSearchSubmit;searchState.input.onchange=e=>{if(e.target!==document.activeElement){return}searchState.clearInputTimeout();setTimeout(search,0)};searchState.input.onpaste=searchState.input.onchange;searchState.outputElement().addEventListener("keydown",e=>{if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey){return}if(e.which===38){const previous=document.activeElement.previousElementSibling;if(previous){previous.focus()}else{searchState.focus()}e.preventDefault()}else if(e.which===40){const next=document.activeElement.nextElementSibling;if(next){next.focus()}const rect=document.activeElement.getBoundingClientRect();if(window.innerHeight-rect.bottom{if(e.which===40){focusSearchResult();e.preventDefault()}});searchState.input.addEventListener("focus",()=>{putBackSearch()});searchState.input.addEventListener("blur",()=>{searchState.input.placeholder=searchState.input.origPlaceholder});if(browserSupportsHistoryApi()){const previousTitle=document.title;window.addEventListener("popstate",e=>{const params=searchState.getQueryStringParams();document.title=previousTitle;currentResults=null;if(params.search&¶ms.search.length>0){searchState.input.value=params.search;e.preventDefault();search()}else{searchState.input.value="";searchState.hideResults()}})}window.onpageshow=()=>{const qSearch=searchState.getQueryStringParams().search;if(searchState.input.value===""&&qSearch){searchState.input.value=qSearch}search()}}function updateCrate(ev){if(ev.target.value==="all crates"){const query=searchState.input.value.trim();updateSearchHistory(buildUrl(query,null))}currentResults=null;search(true)}buildIndex(rawSearchIndex);if(typeof window!=="undefined"){registerSearchEvents();if(window.searchState.getQueryStringParams().search){search()}}if(typeof exports!=="undefined"){exports.initSearch=initSearch;exports.execQuery=execQuery;exports.parseQuery=parseQuery}}if(typeof window!=="undefined"){window.initSearch=initSearch;if(window.searchIndex!==undefined){initSearch(window.searchIndex)}}else{initSearch(new Map())}})() \ No newline at end of file diff --git a/docs/static.files/settings-4313503d2e1961c2.js b/docs/static.files/settings-4313503d2e1961c2.js new file mode 100644 index 00000000..ab425fe4 --- /dev/null +++ b/docs/static.files/settings-4313503d2e1961c2.js @@ -0,0 +1,17 @@ +"use strict";(function(){const isSettingsPage=window.location.pathname.endsWith("/settings.html");function changeSetting(settingName,value){if(settingName==="theme"){const useSystem=value==="system preference"?"true":"false";updateLocalStorage("use-system-theme",useSystem)}updateLocalStorage(settingName,value);switch(settingName){case"theme":case"preferred-dark-theme":case"preferred-light-theme":updateTheme();updateLightAndDark();break;case"line-numbers":if(value===true){window.rustdoc_add_line_numbers_to_examples()}else{window.rustdoc_remove_line_numbers_from_examples()}break;case"hide-sidebar":if(value===true){addClass(document.documentElement,"hide-sidebar")}else{removeClass(document.documentElement,"hide-sidebar")}break}}function showLightAndDark(){removeClass(document.getElementById("preferred-light-theme"),"hidden");removeClass(document.getElementById("preferred-dark-theme"),"hidden")}function hideLightAndDark(){addClass(document.getElementById("preferred-light-theme"),"hidden");addClass(document.getElementById("preferred-dark-theme"),"hidden")}function updateLightAndDark(){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||(useSystem===null&&getSettingValue("theme")===null)){showLightAndDark()}else{hideLightAndDark()}}function setEvents(settingsElement){updateLightAndDark();onEachLazy(settingsElement.querySelectorAll("input[type=\"checkbox\"]"),toggle=>{const settingId=toggle.id;const settingValue=getSettingValue(settingId);if(settingValue!==null){toggle.checked=settingValue==="true"}toggle.onchange=()=>{changeSetting(toggle.id,toggle.checked)}});onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"),elem=>{const settingId=elem.name;let settingValue=getSettingValue(settingId);if(settingId==="theme"){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||settingValue===null){settingValue=useSystem==="false"?"light":"system preference"}}if(settingValue!==null&&settingValue!=="null"){elem.checked=settingValue===elem.value}elem.addEventListener("change",ev=>{changeSetting(ev.target.name,ev.target.value)})})}function buildSettingsPageSections(settings){let output="";for(const setting of settings){const js_data_name=setting["js_name"];const setting_name=setting["name"];if(setting["options"]!==undefined){output+=`\ +
    +
    ${setting_name}
    +
    `;onEach(setting["options"],option=>{const checked=option===setting["default"]?" checked":"";const full=`${js_data_name}-${option.replace(/ /g,"-")}`;output+=`\ + `});output+=`\ +
    +
    `}else{const checked=setting["default"]===true?" checked":"";output+=`\ +
    \ + \ +
    `}}return output}function buildSettingsPage(){const theme_names=getVar("themes").split(",").filter(t=>t);theme_names.push("light","dark","ayu");const settings=[{"name":"Theme","js_name":"theme","default":"system preference","options":theme_names.concat("system preference"),},{"name":"Preferred light theme","js_name":"preferred-light-theme","default":"light","options":theme_names,},{"name":"Preferred dark theme","js_name":"preferred-dark-theme","default":"dark","options":theme_names,},{"name":"Auto-hide item contents for large items","js_name":"auto-hide-large-items","default":true,},{"name":"Auto-hide item methods' documentation","js_name":"auto-hide-method-docs","default":false,},{"name":"Auto-hide trait implementation documentation","js_name":"auto-hide-trait-implementations","default":false,},{"name":"Directly go to item in search if there is only one result","js_name":"go-to-only-result","default":false,},{"name":"Show line numbers on code examples","js_name":"line-numbers","default":false,},{"name":"Hide persistent navigation bar","js_name":"hide-sidebar","default":false,},{"name":"Disable keyboard shortcuts","js_name":"disable-shortcuts","default":false,},];const elementKind=isSettingsPage?"section":"div";const innerHTML=`
    ${buildSettingsPageSections(settings)}
    `;const el=document.createElement(elementKind);el.id="settings";if(!isSettingsPage){el.className="popover"}el.innerHTML=innerHTML;if(isSettingsPage){document.getElementById(MAIN_ID).appendChild(el)}else{el.setAttribute("tabindex","-1");getSettingsButton().appendChild(el)}return el}const settingsMenu=buildSettingsPage();function displaySettings(){settingsMenu.style.display="";onEachLazy(settingsMenu.querySelectorAll("input[type='checkbox']"),el=>{const val=getSettingValue(el.id);const checked=val==="true";if(checked!==el.checked&&val!==null){el.checked=checked}})}function settingsBlurHandler(event){blurHandler(event,getSettingsButton(),window.hidePopoverMenus)}if(isSettingsPage){getSettingsButton().onclick=event=>{event.preventDefault()}}else{const settingsButton=getSettingsButton();const settingsMenu=document.getElementById("settings");settingsButton.onclick=event=>{if(settingsMenu.contains(event.target)){return}event.preventDefault();const shouldDisplaySettings=settingsMenu.style.display==="none";window.hideAllModals();if(shouldDisplaySettings){displaySettings()}};settingsButton.onblur=settingsBlurHandler;settingsButton.querySelector("a").onblur=settingsBlurHandler;onEachLazy(settingsMenu.querySelectorAll("input"),el=>{el.onblur=settingsBlurHandler});settingsMenu.onblur=settingsBlurHandler}setTimeout(()=>{setEvents(settingsMenu);if(!isSettingsPage){displaySettings()}removeClass(getSettingsButton(),"rotate")},0)})() \ No newline at end of file diff --git a/docs/static.files/src-script-e66d777a5a92e9b2.js b/docs/static.files/src-script-e66d777a5a92e9b2.js new file mode 100644 index 00000000..d0aebb85 --- /dev/null +++ b/docs/static.files/src-script-e66d777a5a92e9b2.js @@ -0,0 +1 @@ +"use strict";(function(){const rootPath=getVar("root-path");const NAME_OFFSET=0;const DIRS_OFFSET=1;const FILES_OFFSET=2;const RUSTDOC_MOBILE_BREAKPOINT=700;function closeSidebarIfMobile(){if(window.innerWidth{removeClass(document.documentElement,"src-sidebar-expanded");updateLocalStorage("source-sidebar-show","false")};window.rustdocShowSourceSidebar=()=>{addClass(document.documentElement,"src-sidebar-expanded");updateLocalStorage("source-sidebar-show","true")};window.rustdocToggleSrcSidebar=()=>{if(document.documentElement.classList.contains("src-sidebar-expanded")){window.rustdocCloseSourceSidebar()}else{window.rustdocShowSourceSidebar()}};function createSrcSidebar(){const container=document.querySelector("nav.sidebar");const sidebar=document.createElement("div");sidebar.id="src-sidebar";let hasFoundFile=false;for(const[key,source]of srcIndex){source[NAME_OFFSET]=key;hasFoundFile=createDirEntry(source,sidebar,"",hasFoundFile)}container.appendChild(sidebar);const selected_elem=sidebar.getElementsByClassName("selected")[0];if(typeof selected_elem!=="undefined"){selected_elem.focus()}}function highlightSrcLines(){const match=window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);if(!match){return}let from=parseInt(match[1],10);let to=from;if(typeof match[2]!=="undefined"){to=parseInt(match[2],10)}if(to{onEachLazy(e.getElementsByTagName("a"),i_e=>{removeClass(i_e,"line-highlighted")})});for(let i=from;i<=to;++i){elem=document.getElementById(i);if(!elem){break}addClass(elem,"line-highlighted")}}const handleSrcHighlight=(function(){let prev_line_id=0;const set_fragment=name=>{const x=window.scrollX,y=window.scrollY;if(browserSupportsHistoryApi()){history.replaceState(null,null,"#"+name);highlightSrcLines()}else{location.replace("#"+name)}window.scrollTo(x,y)};return ev=>{let cur_line_id=parseInt(ev.target.id,10);if(isNaN(cur_line_id)||ev.ctrlKey||ev.altKey||ev.metaKey){return}ev.preventDefault();if(ev.shiftKey&&prev_line_id){if(prev_line_id>cur_line_id){const tmp=prev_line_id;prev_line_id=cur_line_id;cur_line_id=tmp}set_fragment(prev_line_id+"-"+cur_line_id)}else{prev_line_id=cur_line_id;set_fragment(cur_line_id)}}}());window.addEventListener("hashchange",highlightSrcLines);onEachLazy(document.getElementsByClassName("src-line-numbers"),el=>{el.addEventListener("click",handleSrcHighlight)});highlightSrcLines();window.createSrcSidebar=createSrcSidebar})() \ No newline at end of file diff --git a/docs/static.files/storage-4c98445ec4002617.js b/docs/static.files/storage-4c98445ec4002617.js new file mode 100644 index 00000000..b378b856 --- /dev/null +++ b/docs/static.files/storage-4c98445ec4002617.js @@ -0,0 +1 @@ +"use strict";const builtinThemes=["light","dark","ayu"];const darkThemes=["dark","ayu"];window.currentTheme=document.getElementById("themeStyle");const settingsDataset=(function(){const settingsElement=document.getElementById("default-settings");return settingsElement&&settingsElement.dataset?settingsElement.dataset:null})();function getSettingValue(settingName){const current=getCurrentValue(settingName);if(current===null&&settingsDataset!==null){const def=settingsDataset[settingName.replace(/-/g,"_")];if(def!==undefined){return def}}return current}const localStoredTheme=getSettingValue("theme");function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className)}function addClass(elem,className){if(elem&&elem.classList){elem.classList.add(className)}}function removeClass(elem,className){if(elem&&elem.classList){elem.classList.remove(className)}}function onEach(arr,func){for(const elem of arr){if(func(elem)){return true}}return false}function onEachLazy(lazyArray,func){return onEach(Array.prototype.slice.call(lazyArray),func)}function updateLocalStorage(name,value){try{window.localStorage.setItem("rustdoc-"+name,value)}catch(e){}}function getCurrentValue(name){try{return window.localStorage.getItem("rustdoc-"+name)}catch(e){return null}}const getVar=(function getVar(name){const el=document.querySelector("head > meta[name='rustdoc-vars']");return el?el.attributes["data-"+name].value:null});function switchTheme(newThemeName,saveTheme){const themeNames=getVar("themes").split(",").filter(t=>t);themeNames.push(...builtinThemes);if(themeNames.indexOf(newThemeName)===-1){return}if(saveTheme){updateLocalStorage("theme",newThemeName)}document.documentElement.setAttribute("data-theme",newThemeName);if(builtinThemes.indexOf(newThemeName)!==-1){if(window.currentTheme){window.currentTheme.parentNode.removeChild(window.currentTheme);window.currentTheme=null}}else{const newHref=getVar("root-path")+encodeURIComponent(newThemeName)+getVar("resource-suffix")+".css";if(!window.currentTheme){if(document.readyState==="loading"){document.write(``);window.currentTheme=document.getElementById("themeStyle")}else{window.currentTheme=document.createElement("link");window.currentTheme.rel="stylesheet";window.currentTheme.id="themeStyle";window.currentTheme.href=newHref;document.documentElement.appendChild(window.currentTheme)}}else if(newHref!==window.currentTheme.href){window.currentTheme.href=newHref}}}const updateTheme=(function(){const mql=window.matchMedia("(prefers-color-scheme: dark)");function updateTheme(){if(getSettingValue("use-system-theme")!=="false"){const lightTheme=getSettingValue("preferred-light-theme")||"light";const darkTheme=getSettingValue("preferred-dark-theme")||"dark";updateLocalStorage("use-system-theme","true");switchTheme(mql.matches?darkTheme:lightTheme,true)}else{switchTheme(getSettingValue("theme"),false)}}mql.addEventListener("change",updateTheme);return updateTheme})();if(getSettingValue("use-system-theme")!=="false"&&window.matchMedia){if(getSettingValue("use-system-theme")===null&&getSettingValue("preferred-dark-theme")===null&&darkThemes.indexOf(localStoredTheme)>=0){updateLocalStorage("preferred-dark-theme",localStoredTheme)}}updateTheme();if(getSettingValue("source-sidebar-show")==="true"){addClass(document.documentElement,"src-sidebar-expanded")}if(getSettingValue("hide-sidebar")==="true"){addClass(document.documentElement,"hide-sidebar")}function updateSidebarWidth(){const desktopSidebarWidth=getSettingValue("desktop-sidebar-width");if(desktopSidebarWidth&&desktopSidebarWidth!=="null"){document.documentElement.style.setProperty("--desktop-sidebar-width",desktopSidebarWidth+"px")}const srcSidebarWidth=getSettingValue("src-sidebar-width");if(srcSidebarWidth&&srcSidebarWidth!=="null"){document.documentElement.style.setProperty("--src-sidebar-width",srcSidebarWidth+"px")}}updateSidebarWidth();window.addEventListener("pageshow",ev=>{if(ev.persisted){setTimeout(updateTheme,0);setTimeout(updateSidebarWidth,0)}}) \ No newline at end of file diff --git a/docs/trait.impl/core/clone/trait.Clone.js b/docs/trait.impl/core/clone/trait.Clone.js new file mode 100644 index 00000000..31a849ad --- /dev/null +++ b/docs/trait.impl/core/clone/trait.Clone.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"fasten":[["impl Clone for Seq"]], +"fasten_convert":[["impl Clone for FastenSeq"]], +"fasten_sort":[["impl Clone for Seq"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/trait.impl/core/fmt/trait.Debug.js b/docs/trait.impl/core/fmt/trait.Debug.js new file mode 100644 index 00000000..45436918 --- /dev/null +++ b/docs/trait.impl/core/fmt/trait.Debug.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"fasten":[["impl Debug for Seq"]], +"fasten_convert":[["impl Debug for FastenSeq"]], +"fasten_sort":[["impl Debug for Seq"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/trait.impl/core/iter/traits/iterator/trait.Iterator.js b/docs/trait.impl/core/iter/traits/iterator/trait.Iterator.js new file mode 100644 index 00000000..f2dcda42 --- /dev/null +++ b/docs/trait.impl/core/iter/traits/iterator/trait.Iterator.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"fasten":[["impl<R: Read> Iterator for FastqReader<R>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/trait.impl/core/marker/trait.Freeze.js b/docs/trait.impl/core/marker/trait.Freeze.js new file mode 100644 index 00000000..daba3ad1 --- /dev/null +++ b/docs/trait.impl/core/marker/trait.Freeze.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"fasten":[["impl<R> Freeze for FastqReader<R>
    where\n R: Freeze,
    ",1,["fasten::io::fastq::FastqReader"]],["impl Freeze for Seq",1,["fasten::io::seq::Seq"]]], +"fasten_convert":[["impl Freeze for FastenSeq",1,["fasten_convert::FastenSeq"]]], +"fasten_sort":[["impl Freeze for Seq",1,["fasten_sort::Seq"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/trait.impl/core/marker/trait.Send.js b/docs/trait.impl/core/marker/trait.Send.js new file mode 100644 index 00000000..28f1f2c4 --- /dev/null +++ b/docs/trait.impl/core/marker/trait.Send.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"fasten":[["impl<R> Send for FastqReader<R>
    where\n R: Send,
    ",1,["fasten::io::fastq::FastqReader"]],["impl Send for Seq",1,["fasten::io::seq::Seq"]]], +"fasten_convert":[["impl Send for FastenSeq",1,["fasten_convert::FastenSeq"]]], +"fasten_sort":[["impl Send for Seq",1,["fasten_sort::Seq"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/trait.impl/core/marker/trait.Sync.js b/docs/trait.impl/core/marker/trait.Sync.js new file mode 100644 index 00000000..ca29df9a --- /dev/null +++ b/docs/trait.impl/core/marker/trait.Sync.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"fasten":[["impl<R> Sync for FastqReader<R>
    where\n R: Sync,
    ",1,["fasten::io::fastq::FastqReader"]],["impl Sync for Seq",1,["fasten::io::seq::Seq"]]], +"fasten_convert":[["impl Sync for FastenSeq",1,["fasten_convert::FastenSeq"]]], +"fasten_sort":[["impl Sync for Seq",1,["fasten_sort::Seq"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/trait.impl/core/marker/trait.Unpin.js b/docs/trait.impl/core/marker/trait.Unpin.js new file mode 100644 index 00000000..cb4c3d14 --- /dev/null +++ b/docs/trait.impl/core/marker/trait.Unpin.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"fasten":[["impl<R> Unpin for FastqReader<R>
    where\n R: Unpin,
    ",1,["fasten::io::fastq::FastqReader"]],["impl Unpin for Seq",1,["fasten::io::seq::Seq"]]], +"fasten_convert":[["impl Unpin for FastenSeq",1,["fasten_convert::FastenSeq"]]], +"fasten_sort":[["impl Unpin for Seq",1,["fasten_sort::Seq"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js b/docs/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js new file mode 100644 index 00000000..f3625329 --- /dev/null +++ b/docs/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"fasten":[["impl<R> RefUnwindSafe for FastqReader<R>
    where\n R: RefUnwindSafe,
    ",1,["fasten::io::fastq::FastqReader"]],["impl RefUnwindSafe for Seq",1,["fasten::io::seq::Seq"]]], +"fasten_convert":[["impl RefUnwindSafe for FastenSeq",1,["fasten_convert::FastenSeq"]]], +"fasten_sort":[["impl RefUnwindSafe for Seq",1,["fasten_sort::Seq"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js b/docs/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js new file mode 100644 index 00000000..626d9532 --- /dev/null +++ b/docs/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"fasten":[["impl<R> UnwindSafe for FastqReader<R>
    where\n R: UnwindSafe,
    ",1,["fasten::io::fastq::FastqReader"]],["impl UnwindSafe for Seq",1,["fasten::io::seq::Seq"]]], +"fasten_convert":[["impl UnwindSafe for FastenSeq",1,["fasten_convert::FastenSeq"]]], +"fasten_sort":[["impl UnwindSafe for Seq",1,["fasten_sort::Seq"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/trait.impl/fasten/io/seq/trait.Cleanable.js b/docs/trait.impl/fasten/io/seq/trait.Cleanable.js new file mode 100644 index 00000000..60ef4870 --- /dev/null +++ b/docs/trait.impl/fasten/io/seq/trait.Cleanable.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"fasten":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file