Expand description
Seqc is a pattern-based encoding library for encoding binary data into human-readable patterns of repeated characters, creating textual representations that resemble visual or rhythmic sequences. It transforms raw bytes into space-separated “words” composed of repeating symbols, where repetition counts encode the original bit patterns.
The library supports customizable “dialects” that define the characters and patterns used, making it flexible
for various encoding needs. It is no_std
compatible by default, with optional std
features for convenience
functions like vector-based encoding and decoding.
§How to use Seqc
There are two primary ways to use Seqc:
- High-level encoding and decoding with dialects provides the simplest interface for most users.
- Use
Dialect<N>
orVariableDialect<N>
to define patterns and perform encoding/decoding operations. - The
encode
anddecode
methods (available withstd
feature) handle vector-based operations efficiently. - For
no_std
environments, useencode_slice
anddecode_slice
for direct buffer manipulation.
- Use
- Custom patterns allow fine-grained control over encoding logic.
- Define individual
Pattern<N>
instances with 2 to 6 distinct characters. - Combine patterns into
VariablePattern<N>
and dialects for variable-length encoding schemes. - Use
encode
anddecode
on patterns for low-level bit manipulation.
- Define individual
§Usage
First, add seqc
to your Cargo.toml
with std
feature enabled.
Next, to use pattern-based encoding, create a dialect with desired patterns and apply it to your data:
use seqc::{Dialect, Pattern, VariablePattern};
let dialect: Dialect<2> = Dialect::new([
VariablePattern::Ternary(Pattern::from([b'a', b'b', b'c'])),
VariablePattern::Quaternary(Pattern::from([b'x', b'y', b'z', b'w'])),
]);
let data = vec![0xAA, 0xBB, 0xCC, 0xDD];
let encoded = dialect.encode(&data);
let decoded = dialect.decode(&encoded).unwrap();
assert_eq!(str::from_utf8(&encoded).unwrap(),
"aaabbbccc xxxyyyzzww aaabbbbcccc xyyyyzw abbbbcc xyyyyzww "
);
assert_eq!(decoded, data);
For no_std
usage, pre-allocate buffers based on measured capacity:
use seqc::{Dialect, Pattern, VariablePattern};
const DIALECT: Dialect<1> = Dialect::new([
VariablePattern::Binary(Pattern::from([b'0', b'1'])),
]);
const DATA: &[u8] = &[0xB4];
let mut buffer = [0u8; DIALECT.measure_encode_capacity(DATA)];
let bytes_written = DIALECT.encode_slice(DATA, &mut buffer).unwrap();
assert_eq!(bytes_written, 14);
assert_eq!(&buffer[..bytes_written], b"001111 011111 ");
§Crate Layout
The main types are organized as follows:
Pattern<N>
: Defines fixed-chunk patterns for encoding 6-bit values.VariablePattern<N>
: Enum for patterns with varying chunk counts (2-6).Dialect<N>
: Fixed-number pattern collections for encoding.VariableDialect<N>
: Enum for dialects with varying pattern counts (1-6).PatternWord
: Represents encoded words in a fixed buffer.DialectError
: Errors for encoding/decoding operations.
Utility functions like Dialect::measure_encode_capacity
help with buffer sizing.
§Edge Cases and Testing
Seqc handles empty inputs, single bytes, and variable lengths robustly. Extensive tests ensure consistency, including round-trip verification and in-place decoding.
For targets without std
, the library relies on core features, maintaining compatibility.
Re-exports§
pub use dialect::Dialect;
pub use dialect::VariableDialect;
pub use error::DialectError;
pub use pattern::Pattern;
pub use pattern::PatternWord;
pub use pattern::VariablePattern;