extern crate encoding_types;
use encoding_types::*;
use std::str::from_utf8;
#[derive(Clone, Copy)]
pub struct ROT13Encoding;
impl Encoding for ROT13Encoding {
fn name(&self) -> &'static str {
"rot13"
}
fn whatwg_name(&self) -> Option<&'static str> {
None
}
fn raw_encoder(&self) -> Box<dyn RawEncoder> {
ROT13Encoder::new()
}
fn raw_decoder(&self) -> Box<dyn RawDecoder> {
ROT13Decoder::new()
}
}
#[derive(Clone, Copy)]
pub struct ROT13Encoder;
impl ROT13Encoder {
#[allow(clippy::new_ret_no_self)]
pub fn new() -> Box<dyn RawEncoder> {
Box::new(ROT13Encoder)
}
}
impl RawEncoder for ROT13Encoder {
fn from_self(&self) -> Box<dyn RawEncoder> {
ROT13Encoder::new()
}
fn is_ascii_compatible(&self) -> bool {
true
}
fn raw_feed(
&mut self,
input: &str,
output: &mut dyn ByteWriter,
) -> (usize, Option<CodecError>) {
output.writer_hint(input.len());
for byte in input.bytes() {
output.write_byte(rotate_byte(byte))
}
(input.len(), None)
}
fn raw_finish(&mut self, _output: &mut dyn ByteWriter) -> Option<CodecError> {
None
}
}
#[derive(Clone, Copy)]
pub struct ROT13Decoder;
impl ROT13Decoder {
#[allow(clippy::new_ret_no_self)]
pub fn new() -> Box<dyn RawDecoder> {
Box::new(ROT13Decoder)
}
}
impl RawDecoder for ROT13Decoder {
fn from_self(&self) -> Box<dyn RawDecoder> {
ROT13Decoder::new()
}
fn is_ascii_compatible(&self) -> bool {
true
}
fn raw_feed(
&mut self,
input: &[u8],
output: &mut dyn StringWriter,
) -> (usize, Option<CodecError>) {
output.writer_hint(input.len());
let string = match from_utf8(input) {
Ok(s) => s,
Err(_e) => {
return (
0,
Some(CodecError {
upto: 0, cause: "input is not valid utf-8".into(),
}),
);
}
};
for ch in string.chars() {
match ch {
'a'..='z' | 'A'..='Z' => output.write_char(rotate_byte(ch as u8) as char),
_ => output.write_char(ch),
}
}
(input.len(), None)
}
fn raw_finish(&mut self, _output: &mut dyn StringWriter) -> Option<CodecError> {
None
}
}
fn rotate_byte(byte: u8) -> u8 {
match byte {
b'a'..=b'm' | b'A'..=b'M' => byte + 13,
b'n'..=b'z' | b'N'..=b'Z' => byte - 13,
_ => byte,
}
}
fn main() {
use std::io;
use std::io::Read;
let mut ret = Vec::new();
io::stdin()
.read_to_end(&mut ret)
.expect("cannot read from the input");
match ROT13Encoding.decode(&ret, DecoderTrap::Strict) {
Ok(s) => println!("{}", s),
Err(e) => panic!("decoder error: {}", e),
};
}