Initial commit
This commit is contained in:
commit
86cd00512a
9 changed files with 410 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
96
Cargo.lock
generated
Normal file
96
Cargo.lock
generated
Normal file
|
@ -0,0 +1,96 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[package]]
|
||||
name = "binary_braillie"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"hex",
|
||||
"num",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.46"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
8
Cargo.toml
Normal file
8
Cargo.toml
Normal file
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "binary_braillie"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
hex = "0.4.3"
|
||||
num = "0.4.3"
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024 Rafał (Wroclaw) F.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
5
README.md
Normal file
5
README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Binary braillie
|
||||
|
||||
Command line tool and API to convert bytes to binary represented in unicode braillie
|
||||
|
||||
it supports how bits should be placed in character, and command line tool supports reversing the input.
|
7
package.nix
Normal file
7
package.nix
Normal file
|
@ -0,0 +1,7 @@
|
|||
{ rustPackages }:
|
||||
|
||||
rustPackages.rustPlatform.buildRustPackage {
|
||||
name = "binary-braillie";
|
||||
src = ./.;
|
||||
cargoSha256 = "sha256-7sbI+bgsI8tTYrV/IZa69eHEc19Mbrk/qh3+9SJ3sGU=";
|
||||
}
|
12
shell.nix
Normal file
12
shell.nix
Normal file
|
@ -0,0 +1,12 @@
|
|||
{ pkgs ? import <nixpkgs> {} }:
|
||||
|
||||
pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
cargo
|
||||
rustc
|
||||
rustfmt
|
||||
];
|
||||
|
||||
RUST_BACKTRACE = 1;
|
||||
RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
|
||||
}
|
148
src/lib.rs
Normal file
148
src/lib.rs
Normal file
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
0 3
|
||||
1 4
|
||||
2 5
|
||||
6 7
|
||||
*/
|
||||
|
||||
use std::u32;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
pub enum EncodeOrientation {
|
||||
// reverse - points in line ordered backwards (direction)
|
||||
// Backwards - major lines ordered backwards (wrap)
|
||||
Rows = 0b00000000,
|
||||
RowsBackwards = 0b00000001,
|
||||
RowsReverse = 0b00000010,
|
||||
RowsBackwardsReverse = 0b00000011,
|
||||
Columns = 0b00000100,
|
||||
ColumnsBackwards = 0b00000101,
|
||||
ColumnsReverse = 0b00000110,
|
||||
ColumnsBackwardsReverse = 0b00000111,
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for EncodeOrientation {
|
||||
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
0 => Ok(EncodeOrientation::Rows),
|
||||
1 => Ok(EncodeOrientation::RowsBackwards),
|
||||
2 => Ok(EncodeOrientation::RowsReverse),
|
||||
3 => Ok(EncodeOrientation::RowsBackwardsReverse),
|
||||
4 => Ok(EncodeOrientation::Columns),
|
||||
5 => Ok(EncodeOrientation::ColumnsBackwards),
|
||||
6 => Ok(EncodeOrientation::ColumnsReverse),
|
||||
7 => Ok(EncodeOrientation::ColumnsBackwardsReverse),
|
||||
_ => panic!("Unknown encode orientation provided")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const MAPPINGS: [[u8; 8]; 8] = [
|
||||
[0, 3, 1, 4, 2, 5, 6, 7],
|
||||
[6, 7, 2, 5, 1, 4, 0, 3],
|
||||
[3, 0, 4, 1, 5, 2, 7, 6],
|
||||
[7, 6, 5, 2, 4, 1, 3, 0],
|
||||
[0, 1, 2, 6, 3, 4, 5, 7],
|
||||
[3, 4, 5, 7, 0, 1, 2, 6],
|
||||
[6, 2, 1, 0, 7, 5, 4, 3],
|
||||
[7, 5, 4, 3, 6, 2, 1, 0]
|
||||
];
|
||||
|
||||
pub fn index_to_braillie_char(_index: u8, mode: EncodeOrientation) -> char {
|
||||
let mapping = MAPPINGS[mode as usize];
|
||||
let index: u8 =
|
||||
((_index >> 7) & 1) << mapping[0]
|
||||
| ((_index >> 6) & 1) << mapping[1]
|
||||
| ((_index >> 5) & 1) << mapping[2]
|
||||
| ((_index >> 4) & 1) << mapping[3]
|
||||
| ((_index >> 3) & 1) << mapping[4]
|
||||
| ((_index >> 2) & 1) << mapping[5]
|
||||
| ((_index >> 1) & 1) << mapping[6]
|
||||
| ((_index >> 0) & 1) << mapping[7];
|
||||
return char::from_u32(0x2800 + index as u32).unwrap();
|
||||
}
|
||||
|
||||
pub fn to_binary_braillie(input: &[u8], length: usize, mode: EncodeOrientation) -> String {
|
||||
let mut rvalue = String::with_capacity(length);
|
||||
for i in 0..length {
|
||||
rvalue.push(index_to_braillie_char(input[i], mode));
|
||||
}
|
||||
return rvalue;
|
||||
}
|
||||
|
||||
pub fn to_binary_braillie_str(input: impl AsRef<str>, mode: EncodeOrientation) -> String {
|
||||
return to_binary_braillie(input.as_ref().as_bytes(), input.as_ref().len(), mode);
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_lib {
|
||||
use crate::{index_to_braillie_char, to_binary_braillie_str, EncodeOrientation};
|
||||
|
||||
#[test]
|
||||
fn check_characters_in_range() {
|
||||
for i in 0..0xff {
|
||||
let char = index_to_braillie_char(i, EncodeOrientation::Rows);
|
||||
assert!(0x2800 <= char as u32 && char as u32 <= 0x28ff);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_individual_bits() {
|
||||
assert_eq!(
|
||||
index_to_braillie_char(0b10000000, EncodeOrientation::Rows),
|
||||
char::from_u32(0x2800 + 0b00000001).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
index_to_braillie_char(0b01000000, EncodeOrientation::Rows),
|
||||
char::from_u32(0x2800 + 0b00001000).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
index_to_braillie_char(0b00100000, EncodeOrientation::Rows),
|
||||
char::from_u32(0x2800 + 0b00000010).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
index_to_braillie_char(0b00010000, EncodeOrientation::Rows),
|
||||
char::from_u32(0x2800 + 0b00010000).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
index_to_braillie_char(0b00001000, EncodeOrientation::Rows),
|
||||
char::from_u32(0x2800 + 0b00000100).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
index_to_braillie_char(0b00000100, EncodeOrientation::Rows),
|
||||
char::from_u32(0x2800 + 0b00100000).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
index_to_braillie_char(0b00000010, EncodeOrientation::Rows),
|
||||
char::from_u32(0x2800 + 0b01000000).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
index_to_braillie_char(0b00000001, EncodeOrientation::Rows),
|
||||
char::from_u32(0x2800 + 0b10000000).unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_some_strings() {
|
||||
assert_eq!(
|
||||
to_binary_braillie_str("Hi", EncodeOrientation::Rows),
|
||||
"⠌⢎"
|
||||
);
|
||||
assert_eq!(
|
||||
to_binary_braillie_str("Hello, world!", EncodeOrientation::Rows),
|
||||
"⠌⢪⠮⠮⣮⠦⠂⣺⣮⡚⠮⠪⢂"
|
||||
);
|
||||
assert_eq!(
|
||||
to_binary_braillie_str("ąęćó", EncodeOrientation::Rows),
|
||||
"⠩⢡⠩⢕⠩⣡⣉⣓"
|
||||
);
|
||||
}
|
||||
}
|
112
src/main.rs
Normal file
112
src/main.rs
Normal file
|
@ -0,0 +1,112 @@
|
|||
use std::env;
|
||||
use std::process::exit;
|
||||
|
||||
use binary_braillie::to_binary_braillie;
|
||||
|
||||
fn main() {
|
||||
let args = parse_args();
|
||||
if args.value_to_convert.len() <= 0 {
|
||||
print!("{}: No input specified!", args.program_name)
|
||||
}
|
||||
let mut value: Vec<u8> = if !args.hexadecimal {
|
||||
Vec::from(args.value_to_convert.as_bytes())
|
||||
}
|
||||
else {
|
||||
Vec::from(hex::decode(args.value_to_convert).unwrap_or_else(
|
||||
|_e_| {
|
||||
print!("{}: Invalid hex provided", args.program_name);
|
||||
exit(128);
|
||||
})
|
||||
)};
|
||||
|
||||
if args.reverse_characters { value.reverse(); }
|
||||
|
||||
print!("{}", to_binary_braillie(&value, value.len(), args.mode.try_into().unwrap()))
|
||||
}
|
||||
|
||||
struct Arguments {
|
||||
pub hexadecimal: bool,
|
||||
pub mode: u8,
|
||||
pub program_name: String,
|
||||
pub reverse_characters: bool,
|
||||
pub value_to_convert: String,
|
||||
}
|
||||
|
||||
fn parse_args() -> Arguments {
|
||||
let mut args = env::args().peekable();
|
||||
let mut rvalue = Arguments {
|
||||
hexadecimal: false,
|
||||
mode: 0,
|
||||
program_name: args.next().unwrap_or(String::from("t2br")),
|
||||
reverse_characters: false,
|
||||
value_to_convert: String::new(),
|
||||
};
|
||||
let program_name = &rvalue.program_name;
|
||||
|
||||
while args.peek() != None {
|
||||
let arg = args.next().unwrap();
|
||||
|
||||
if arg == "--help"
|
||||
|| arg == "-h"
|
||||
|| arg == "-?"
|
||||
{
|
||||
print_help(rvalue.program_name);
|
||||
exit(1);
|
||||
}
|
||||
else if arg == "--hex" {
|
||||
rvalue.hexadecimal = true;
|
||||
}
|
||||
else if arg == "--direction" {
|
||||
let direction = args.next().unwrap_or_else(|| {
|
||||
println!("{}: argument for {} was not provided", program_name, arg);
|
||||
exit(64);
|
||||
});
|
||||
match direction.as_str() {
|
||||
"row" => { rvalue.mode &= !(1 << 1) ; rvalue.mode &= !(1 << 2); }
|
||||
"row-reverse" => { rvalue.mode |= 1 << 1 ; rvalue.mode &= !(1 << 2); }
|
||||
"column" => { rvalue.mode &= !(1 << 1) ; rvalue.mode |= 1 << 2 ; }
|
||||
"column-reverse" => { rvalue.mode |= 1 << 1 ; rvalue.mode |= 1 << 2 ; }
|
||||
_ => {
|
||||
println!("{}: invalid direction \"{}\" provided", program_name, direction);
|
||||
exit(65);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if arg == "--wrap" {
|
||||
let wrap = args.next().unwrap_or_else(|| {
|
||||
println!("{}: argument for {} was not provided", program_name, arg);
|
||||
exit(64);
|
||||
});
|
||||
match wrap.as_str() {
|
||||
"normal" => rvalue.mode &= !(1 << 0),
|
||||
"reverse" => rvalue.mode |= 1 << 0,
|
||||
_ => {
|
||||
println!("{}: invalid wrap \"{}\" provided", program_name, wrap);
|
||||
exit(65);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if arg == "-r"
|
||||
|| arg == "--reverse" {
|
||||
rvalue.reverse_characters = true;
|
||||
}
|
||||
else {
|
||||
if rvalue.value_to_convert.len() > 0 { rvalue.value_to_convert.push(' '); };
|
||||
rvalue.value_to_convert.push_str(&arg);
|
||||
}
|
||||
}
|
||||
|
||||
return rvalue;
|
||||
}
|
||||
|
||||
fn print_help(program_name: String) {
|
||||
print!("Usage: {program_name} [options] <input>\n");
|
||||
print!("Convert input to binary represented in braillie characters\n\n");
|
||||
print!(" --hex convert hexadecimal to braillie represented binary\n\n");
|
||||
print!(" --direction [mode] direction of bits per character\n");
|
||||
print!(" possible values: row, row-reverse, column, column-reverse\n\n");
|
||||
print!(" --wrap [mode] direction of bits wrapping per character\n");
|
||||
print!(" possible values: normal, reverse\n\n");
|
||||
print!(" -r, --reverse reverse outputted characters\n\n");
|
||||
print!(" -h, -?, --help display this help and exit");
|
||||
}
|
Loading…
Reference in a new issue