[−][src]Struct rot::RotU8
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
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!(); }
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]
N: Integer,
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]
M: Add<N> + Integer,
<M as Add<N>>::Output: Integer,
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]
N: Rem<P26> + Integer,
<N as Rem<P26>>::Output: Integer + Same<Z0>,
impl<N: Copy + Integer> Copy for RotU8<N>
[src]
impl<N: Clone + Integer> Clone for RotU8<N>
[src]
fn clone(&self) -> 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]
N: Integer,
impl<N: Integer> Debug for RotU8<N>
[src]
impl<N: Integer> Display for RotU8<N>
[src]
Auto Trait Implementations
Blanket Implementations
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
fn to_owned(&self) -> T
[src]
fn clone_into(&self, target: &mut T)
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> ToString for T where
T: Display + ?Sized,
[src]
T: Display + ?Sized,
impl<T> From<T> for T
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Same<T> for T
[src]
type Output = T
Should always be Self