[−][src]Crate char_circle
A circular buffer for strings and traits for in-place string transforms.
This crate provides two key types: the CharCircle
struct and the
StringTransform
trait. The CharCircle
is a circular buffer
specialized for UTF-8 strings, and the StringTransform
trait builds upon
it to provide a character-oriented API for in-place string transformations.
In short, StringTransform
allows you to implement transformations as
iterator adaptors, with copy-on-write optimizations in mind.
The CharCircle
uses internal mutability. This enables its contents to be
consumed by an external iterator, Chars
. As a consequence, the
CharCircle
is not Sync
. It is implemented as a RefCell
around the
RawCircle
, which has a nearly identical API, uses external mutability,
is thread-safe, and does not provide a consuming iterator.
The StringTransform
trait is implemented by factories of iterator
adaptors. For simple cases, the SimpleTransform
trait provides an
alternative that is implemented directly by the adaptor.
Example: To Uppercase
Transforms which don't require configuration are most easily implemented
with SimpleTransform
.
Here we implement an uppercase transform:
use char_circle::{SimpleTransform, Chars}; // Step 1: Define the transform as an iterator adaptor. struct ToUpper<I>(I); impl<I> Iterator for ToUpper<I> where I: Iterator<Item=char> { type Item = char; fn next(&mut self) -> Option<char> { self.0.next().map(|ch| ch.to_ascii_uppercase()) } } // Step 2: Define a constructor for the adaptor with `SimpleTransform`. impl<'a> SimpleTransform<'a> for ToUpper<Chars<'a>> { fn transform_chars(chars: Chars<'a>) -> Self { ToUpper(chars) } } // Step 3: Profit! let s = "can you hear me in the back?"; let s = ToUpper::transform(s); assert_eq!(&s, "CAN YOU HEAR ME IN THE BACK?");
Example: Caesar Cipher
Transforms that need to be configured should define a factory which
implements StringTransform
.
Here we implement a Caesar cipher configured with its key:
use char_circle::{StringTransform, Chars}; // Step 1: Define the transform as an iterator adaptor. struct CaesarCipherIter<I> { inner: I, key: i32, } impl<I> Iterator for CaesarCipherIter<I> where I: Iterator<Item=char> { type Item = char; fn next(&mut self) -> Option<char> { let plaintext = self.inner.next()?; let ciphertext = plaintext as i32 + self.key; let ciphertext = std::char::from_u32(ciphertext as u32).unwrap(); Some(ciphertext) } } // Step 2: Define a factory for the adaptor with `StringTransform`. struct CaesarCipher(i32); impl<'a> StringTransform<'a> for CaesarCipher { type Iter = CaesarCipherIter<Chars<'a>>; fn transform_chars(&self, chars: Chars<'a>) -> Self::Iter { CaesarCipherIter { inner: chars, key: self.0 } } } // Step 3: Profit! let encoder = CaesarCipher(8); let decoder = CaesarCipher(-8); let plaintext = "Veni, vidi, vici"; let ciphertext = encoder.transform(plaintext); assert_eq!(&ciphertext, "^mvq4(~qlq4(~qkq"); let plaintext = decoder.transform(ciphertext); assert_eq!(&plaintext, "Veni, vidi, vici");
Structs
CharCircle | A circular buffer of characters. |
Chars | An iterator that consumes characters in a |
RawCircle | A thread-safe version of |
SimpleStringTransform | Used when you have a |
Traits
SimpleTransform | A simple trait for in-place string transformations. |
StringTransform | A factory trait for in-place string transformations. |