Initial commit
This commit is contained in:
commit
3ab6634661
5 changed files with 194 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
7
Cargo.lock
generated
Normal file
7
Cargo.lock
generated
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "b2"
|
||||||
|
version = "0.1.0"
|
6
Cargo.toml
Normal file
6
Cargo.toml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[package]
|
||||||
|
name = "b2"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
176
src/encode.rs
Normal file
176
src/encode.rs
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
use std::io::{self, ErrorKind, Read, Write};
|
||||||
|
|
||||||
|
#[derive(Default, Clone, Copy)]
|
||||||
|
pub enum Style {
|
||||||
|
#[default]
|
||||||
|
Plain,
|
||||||
|
Spaces,
|
||||||
|
Prefixed,
|
||||||
|
Table,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Encoder<R: Read, W: Write> {
|
||||||
|
reader: R,
|
||||||
|
writer: W,
|
||||||
|
style: Style,
|
||||||
|
wrap: Option<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: Read, W: Write> Encoder<R, W> {
|
||||||
|
pub fn new(reader: R, writer: W, style: Option<Style>, mut wrap: Option<usize>) -> Self {
|
||||||
|
let style = style.unwrap_or_default();
|
||||||
|
if let Style::Table = style {
|
||||||
|
wrap = match wrap {
|
||||||
|
Some(u) => Some(u),
|
||||||
|
None => Some(5),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Self {
|
||||||
|
reader,
|
||||||
|
writer,
|
||||||
|
style,
|
||||||
|
wrap,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encode(mut self) -> Result<W, io::Error> {
|
||||||
|
let mut bytes = self.reader.bytes();
|
||||||
|
let mut total = 0;
|
||||||
|
loop {
|
||||||
|
match bytes.next() {
|
||||||
|
Some(Ok(b)) => match self.style {
|
||||||
|
Style::Plain => {
|
||||||
|
if let Some(w) = self.wrap {
|
||||||
|
if total > 0 && total % w == 0 {
|
||||||
|
writeln!(self.writer)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
write!(self.writer, "{b:08b}")?;
|
||||||
|
}
|
||||||
|
Style::Spaces => {
|
||||||
|
if let Some(w) = self.wrap {
|
||||||
|
if total > 0 && total % w == 0 {
|
||||||
|
writeln!(self.writer)?;
|
||||||
|
} else {
|
||||||
|
write!(self.writer, " ")?;
|
||||||
|
}
|
||||||
|
} else if total > 0 {
|
||||||
|
write!(self.writer, " ")?;
|
||||||
|
}
|
||||||
|
write!(self.writer, "{b:08b}")?;
|
||||||
|
}
|
||||||
|
Style::Prefixed => {
|
||||||
|
if let Some(w) = self.wrap {
|
||||||
|
if total > 0 && total % w == 0 {
|
||||||
|
writeln!(self.writer)?;
|
||||||
|
} else if total > 0 {
|
||||||
|
write!(self.writer, " ")?;
|
||||||
|
}
|
||||||
|
} else if total > 0 {
|
||||||
|
write!(self.writer, " ")?;
|
||||||
|
}
|
||||||
|
write!(self.writer, "{b:#010b}")?;
|
||||||
|
}
|
||||||
|
Style::Table => {
|
||||||
|
if let Some(w) = self.wrap {
|
||||||
|
if total % w == 0 {
|
||||||
|
if total > 0 {
|
||||||
|
write!(self.writer, "\n{total:>5}\t{b:#010b}")?;
|
||||||
|
} else {
|
||||||
|
write!(self.writer, "{total:>5}\t{b:#010b}")?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
write!(self.writer, " {b:#010b}")?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Some(Err(e)) if e.kind() == ErrorKind::UnexpectedEof => break,
|
||||||
|
Some(Err(e)) if e.kind() == ErrorKind::Interrupted => continue,
|
||||||
|
Some(Err(e)) => return Err(e),
|
||||||
|
None => break,
|
||||||
|
}
|
||||||
|
total += 1;
|
||||||
|
}
|
||||||
|
if let Some(w) = self.wrap {
|
||||||
|
if total % w != 0 {
|
||||||
|
writeln!(self.writer)?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
writeln!(self.writer)?;
|
||||||
|
}
|
||||||
|
Ok(self.writer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn hello_plain() {
|
||||||
|
let encoder = Encoder::new("Hello, World!".as_bytes(), vec![], None, None);
|
||||||
|
assert_eq!(
|
||||||
|
encoder.encode().unwrap(),
|
||||||
|
b"01001000011001010110110001101100011011110010110000100000010101110110111101110010011011000110010000100001\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn hello_spaced() {
|
||||||
|
let encoder = Encoder::new(
|
||||||
|
"Hello, World!".as_bytes(),
|
||||||
|
vec![],
|
||||||
|
Some(Style::Spaces),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
encoder.encode().unwrap(),
|
||||||
|
b"01001000 01100101 01101100 01101100 01101111 00101100 00100000 01010111 01101111 01110010 01101100 01100100 00100001\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn hello_prefixed() {
|
||||||
|
let encoder = Encoder::new(
|
||||||
|
"Hello, World!".as_bytes(),
|
||||||
|
vec![],
|
||||||
|
Some(Style::Prefixed),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
encoder.encode().unwrap(),
|
||||||
|
b"0b01001000 0b01100101 0b01101100 0b01101100 0b01101111 0b00101100 0b00100000 0b01010111 0b01101111 0b01110010 0b01101100 0b01100100 0b00100001\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn hello_prefixed_wrapped() {
|
||||||
|
let encoder = Encoder::new(
|
||||||
|
"Hello, World!".as_bytes(),
|
||||||
|
vec![],
|
||||||
|
Some(Style::Prefixed),
|
||||||
|
Some(4),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
encoder.encode().unwrap(),
|
||||||
|
b"0b01001000 0b01100101 0b01101100 0b01101100\n0b01101111 0b00101100 0b00100000 0b01010111\n0b01101111 0b01110010 0b01101100 0b01100100\n0b00100001\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn hello_table() {
|
||||||
|
let encoder = Encoder::new(
|
||||||
|
"Hello, World!".as_bytes(),
|
||||||
|
vec![],
|
||||||
|
Some(Style::Table),
|
||||||
|
Some(4),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
encoder.encode().unwrap(),
|
||||||
|
b" 0\t0b01001000 0b01100101 0b01101100 0b01101100\n 4\t0b01101111 0b00101100 0b00100000 0b01010111\n 8\t0b01101111 0b01110010 0b01101100 0b01100100\n 12\t0b00100001\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
4
src/lib.rs
Normal file
4
src/lib.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#![warn(clippy::all, clippy::pedantic)]
|
||||||
|
|
||||||
|
mod encode;
|
||||||
|
pub use encode::{Encoder, Style};
|
Loading…
Add table
Reference in a new issue