Skip to content

Commit

Permalink
Properly handle single bytes
Browse files Browse the repository at this point in the history
  • Loading branch information
alajpie committed Jun 16, 2020
1 parent 8ce9d3d commit 9f323ca
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 15 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "urbit-q"
version = "0.1.2"
version = "0.2.0"
authors = ["k2l8m11n2"]
edition = "2018"
description = "Encode and decode data in Urbit's @q format"
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ Based on [urbit-ob](https://github.com/urbit/urbit-ob), supports only the `@q` f

## usage

Note that `encode` pads the beginning to an even number of bytes (as per the
original implementation) and `decode` ignores any dashes or spaces within the
string.
Note that when encoding more than one byte, `encode` pads from the beginning to
an even number (as per the original implementation) and `decode` ignores any
dashes or spaces within the string.
```rust
let bytes: [u8; 3] = [1, 2, 3];
let string = urbit_q::encode(&bytes); // doznec-binwes
urbit_q::encode(&[1]); // nec
let string = urbit_q::encode(&[1, 2, 3]); // doznec-binwes
urbit_q::decode(&string).unwrap(); // [0, 1, 2, 3]
urbit_q::decode("doz nec bin wes"); // Some([0, 1, 2, 3])
urbit_q::decode("do-z ne cb inwes"); // Some([0, 1, 2, 3])
Expand Down
19 changes: 14 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
//!
//! ## usage
//!
//! Note that `encode` pads the beginning to an even number of bytes (as per the
//! original implementation) and `decode` ignores any dashes or spaces within the
//! string.
//! Note that when encoding more than one byte, `encode` pads from the beginning to
//! an even number (as per the original implementation) and `decode` ignores any
//! dashes or spaces within the string.
//! ```rust
//! let bytes: [u8; 3] = [1, 2, 3];
//! let string = urbit_q::encode(&bytes); // doznec-binwes
//! urbit_q::encode(&[1]); // nec
//! let string = urbit_q::encode(&[1, 2, 3]); // doznec-binwes
//! urbit_q::decode(&string).unwrap(); // [0, 1, 2, 3]
//! urbit_q::decode("doz nec bin wes"); // Some([0, 1, 2, 3])
//! urbit_q::decode("do-z ne cb inwes"); // Some([0, 1, 2, 3])
Expand All @@ -29,6 +29,12 @@ mod consts;
/// decode(&string).unwrap(); // [0, 1, 2, 3]
/// ```
pub fn encode(input: &[u8]) -> String {
if input.len() == 0 {
return String::new();
}
if input.len() == 1 {
return String::from(consts::SUFFIXES[input[0] as usize]);
}
let should_pad = input.len() % 2 != 0;
let length = input.len() + should_pad as usize;
let dashes = if input.len() > 2 { length / 2 - 1 } else { 0 };
Expand Down Expand Up @@ -73,6 +79,9 @@ pub fn decode(input: &str) -> Option<Vec<u8>> {
return None;
}
let stripped_input = input.replace(&['-', ' '][..], "");
if stripped_input.len() == 3 {
return Some(vec![*consts::SUFFIXES_MAP.get(&stripped_input[..])?]);
}
if stripped_input.len() % 3 != 0 {
return None;
}
Expand Down
25 changes: 23 additions & 2 deletions tests/manual.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
#[test]
fn readme() {
let bytes: [u8; 3] = [1, 2, 3];
let string = urbit_q::encode(&bytes);
assert_eq!(urbit_q::encode(&[1]), "nec");
let string = urbit_q::encode(&[1, 2, 3]);
assert_eq!(string, "doznec-binwes");
assert_eq!(urbit_q::decode(&string).unwrap(), vec![0, 1, 2, 3]);
assert_eq!(urbit_q::decode("doz nec bin wes"), Some(vec!(0, 1, 2, 3)));
assert_eq!(urbit_q::decode("do-z ne cb inwes"), Some(vec!(0, 1, 2, 3)));
assert_eq!(urbit_q::decode("hello world"), None);
}

#[test]
fn simple() {
assert_eq!(urbit_q::encode(&[]), "");
assert_eq!(urbit_q::decode(""), Some(vec![]));
assert_eq!(urbit_q::encode(&[0]), "zod");
assert_eq!(urbit_q::decode("zod"), Some(vec![0]));
assert_eq!(urbit_q::encode(&[1]), "nec");
assert_eq!(urbit_q::decode("nec"), Some(vec![1]));
assert_eq!(urbit_q::encode(&[1, 2]), "marbud");
assert_eq!(urbit_q::decode("marbud"), Some(vec![1, 2]));
assert_eq!(urbit_q::encode(&[1, 2, 3]), "doznec-binwes");
assert_eq!(urbit_q::decode("doznec-binwes"), Some(vec![0, 1, 2, 3]));
assert_eq!(urbit_q::encode(&[1, 2, 3, 4]), "marbud-wansev");
assert_eq!(urbit_q::decode("marbud-wansev"), Some(vec![1, 2, 3, 4]));
assert_eq!(urbit_q::encode(&[1, 2, 3, 4, 5]), "doznec-binwes-samper");
assert_eq!(
urbit_q::decode("doznec-binwes-samper"),
Some(vec![0, 1, 2, 3, 4, 5])
);
}
2 changes: 1 addition & 1 deletion tests/proptest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ proptest! {
#[test]
fn roundtrip(bytes: Vec<u8>) {
let mut padded = bytes.clone();
if padded.len() % 2 != 0{
if padded.len() != 1 && padded.len() % 2 != 0 {
padded.insert(0, 0);
}
let tripped = decode(&encode(&bytes)).unwrap();
Expand Down

0 comments on commit 9f323ca

Please sign in to comment.