[][src]Struct rot::RotU8

pub struct RotU8<N: Integer>(_, _);

A wrapper over Ascii u8 which rotates alphabetic characters by N. This is essentially a per-character Caesar cipher with a shift of N. A collection of this type may also be used to implement a strongly-typed Vigenère cipher. An interesting characteristic is that this type can only be converted back to a raw u8 when it has been rotated back into place (i.e N % 26 == 0), otherwise it is a compile-time type error to do so. It is also type-parameterized over the rotation length to prevent partial/improper ciphers at compile-time. This makes it impossible to use a byte rotated right by 12 when a type contract requires a byte rotated left by 13, for example.

Examples

Rotate some u8 bytes by 7 positions to the right.

use rot::{Rotate, RotU8};
use typenum::consts::P7;
let s = "a b c";
let r : Vec<RotU8<P7>> = s.bytes().rotate_by::<P7>().collect();

Try to incorrectly read a rotated byte

This example deliberately fails to compile
use rot::{Rotate, RotU8};
use typenum::consts::P1;
let c = 'a' as u8;
let rotated: RotU8<P1> = c.into();
let contents: u8 = rotated.into();  // This will fail to type check!

Perform no-op rotations

use rot::{Rotate, RotU8};
use typenum::consts::{Z0, P26};
let c = 'a' as u8;
let rotated_by_zero: RotU8<Z0> = c.into();
let rotated_by_26: RotU8<P26> = c.into();
let contents_0: u8 = rotated_by_zero.into();  // This works, `c` wasn't rotated.
assert_eq!(contents_0, 'a' as u8);
// This works, `c` was rotated back to the start point.
let contents_26: u8 = rotated_by_26.into();
assert_eq!(contents_26, 'a' as u8);

Type safe signatures

use typenum::{Integer};
use typenum::consts::{Z0, P1, N1};
use rot::RotU8;

// This function cannot secretly rotate the byte (unless it rotates it back!)
// This would be useful in a trait definition to enforce a stronger contract.
fn should_not_rotate<N: Integer>(rc: RotU8<N>) -> RotU8<N> {
    unimplemented!();
}
This example deliberately fails to compile
use typenum::{Integer};
use typenum::consts::{Z0, P1, N1};
use rot::RotU8;

fn evil_function<N: Integer>(rc: RotU8<N>) -> RotU8<N> {
    rc.rotate_by::<P1>() // Compile-time error!
    // ^ this has type RotU8<N+1>
}
use typenum::{Integer};
use typenum::consts::{Z0, P1, N1};
use rot::RotU8;

fn not_so_evil_function<N: Integer>(rc: RotU8<N>) -> RotU8<N> {
    rc.rotate_by::<Z0>() // Works fine! Adding zero (or a multiple of 26) doesn't rotate.
}

Methods

impl<N> RotU8<N> where
    N: Integer
[src]

pub fn as_raw(&self) -> u8[src]

Get the raw underlying u8 in rotated form.

use typenum::consts::P1;
use rot::RotU8;
 
let rotated : RotU8<P1> = ('a' as u8).into();
assert_eq!(rotated.as_raw(), 'a' as u8 + 1);

pub fn rotate_by<M>(self) -> RotU8<Sum<M, N>> where
    M: Add<N> + Integer,
    <M as Add<N>>::Output: Integer
[src]

Chain a rotation by N with a rotation by M.

use typenum::consts::{P1, P2, P3, N1, N4};
use rot::RotU8;

let rotate_by_one: RotU8<P1> = ('a' as u8).into();
let rotate_by_three: RotU8<P3> = rotate_by_one.rotate_by::<P2>();
assert_eq!(rotate_by_three.as_raw(), 'd' as u8);
let rotate_back: RotU8<N1> = rotate_by_three.rotate_by::<N4>();
assert_eq!(rotate_back.as_raw(), 'z' as u8);

Trait Implementations

impl<'a, N> Into<u8> for RotU8<N> where
    N: Rem<P26> + Integer,
    <N as Rem<P26>>::Output: Integer + Same<Z0>, 
[src]

impl<N: Copy + Integer> Copy for RotU8<N>[src]

impl<N: Clone + Integer> Clone for RotU8<N>[src]

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

impl<N> From<u8> for RotU8<N> where
    N: Integer
[src]

impl<N: Integer> Debug for RotU8<N>[src]

impl<N: Integer> Display for RotU8<N>[src]

Auto Trait Implementations

impl<N> Send for RotU8<N> where
    N: Send

impl<N> Sync for RotU8<N> where
    N: Sync

Blanket Implementations

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Same<T> for T[src]

type Output = T

Should always be Self