Change encode
to be a method of Term
This commit is contained in:
parent
bc319d3089
commit
7cb5ff2fc2
2 changed files with 73 additions and 70 deletions
135
src/enc/mod.rs
135
src/enc/mod.rs
|
@ -46,7 +46,7 @@ impl<'a, 'b> Encode for dec::Term<'a, 'b> {
|
||||||
/// ```
|
/// ```
|
||||||
/// use nettext::enc::*;
|
/// use nettext::enc::*;
|
||||||
///
|
///
|
||||||
/// assert_eq!(encode(string("Hello world .").unwrap()), b"Hello world .");
|
/// assert_eq!(string("Hello world .").unwrap().encode(), b"Hello world .");
|
||||||
/// ```
|
/// ```
|
||||||
pub fn string(s: &str) -> Result<'_> {
|
pub fn string(s: &str) -> Result<'_> {
|
||||||
for c in s.as_bytes().iter() {
|
for c in s.as_bytes().iter() {
|
||||||
|
@ -62,7 +62,7 @@ pub fn string(s: &str) -> Result<'_> {
|
||||||
/// ```
|
/// ```
|
||||||
/// use nettext::enc::*;
|
/// use nettext::enc::*;
|
||||||
///
|
///
|
||||||
/// assert_eq!(encode(raw(b"Hello { a = b, c = d} .").unwrap()), b"Hello { a = b, c = d} .");
|
/// assert_eq!(raw(b"Hello { a = b, c = d} .").unwrap().encode(), b"Hello { a = b, c = d} .");
|
||||||
/// ```
|
/// ```
|
||||||
pub fn raw(bytes: &[u8]) -> Result<'_> {
|
pub fn raw(bytes: &[u8]) -> Result<'_> {
|
||||||
if decode(bytes).is_err() {
|
if decode(bytes).is_err() {
|
||||||
|
@ -76,10 +76,10 @@ pub fn raw(bytes: &[u8]) -> Result<'_> {
|
||||||
/// ```
|
/// ```
|
||||||
/// use nettext::enc::*;
|
/// use nettext::enc::*;
|
||||||
///
|
///
|
||||||
/// assert_eq!(encode(list([
|
/// assert_eq!(list([
|
||||||
/// string("Hello").unwrap(),
|
/// string("Hello").unwrap(),
|
||||||
/// string("world").unwrap()
|
/// string("world").unwrap()
|
||||||
/// ]).unwrap()), b"Hello world");
|
/// ]).unwrap().encode(), b"Hello world");
|
||||||
/// ```
|
/// ```
|
||||||
pub fn list<'a, I: IntoIterator<Item = Term<'a>>>(terms: I) -> Result<'a> {
|
pub fn list<'a, I: IntoIterator<Item = Term<'a>>>(terms: I) -> Result<'a> {
|
||||||
let mut tmp = Vec::with_capacity(8);
|
let mut tmp = Vec::with_capacity(8);
|
||||||
|
@ -97,10 +97,10 @@ pub fn list<'a, I: IntoIterator<Item = Term<'a>>>(terms: I) -> Result<'a> {
|
||||||
/// ```
|
/// ```
|
||||||
/// use nettext::enc::*;
|
/// use nettext::enc::*;
|
||||||
///
|
///
|
||||||
/// assert_eq!(encode(dict([
|
/// assert_eq!(dict([
|
||||||
/// ("a", string("Hello").unwrap()),
|
/// ("a", string("Hello").unwrap()),
|
||||||
/// ("b", string("world").unwrap())
|
/// ("b", string("world").unwrap())
|
||||||
/// ])), b"{\n a = Hello,\n b = world,\n}");
|
/// ]).encode(), b"{\n a = Hello,\n b = world,\n}");
|
||||||
/// ```
|
/// ```
|
||||||
pub fn dict<'a, I: IntoIterator<Item = (&'a str, Term<'a>)>>(pairs: I) -> Term<'a> {
|
pub fn dict<'a, I: IntoIterator<Item = (&'a str, Term<'a>)>>(pairs: I) -> Term<'a> {
|
||||||
let mut tmp = HashMap::new();
|
let mut tmp = HashMap::new();
|
||||||
|
@ -118,7 +118,7 @@ pub fn dict<'a, I: IntoIterator<Item = (&'a str, Term<'a>)>>(pairs: I) -> Term<'
|
||||||
/// ```
|
/// ```
|
||||||
/// use nettext::enc::*;
|
/// use nettext::enc::*;
|
||||||
///
|
///
|
||||||
/// assert_eq!(encode(bytes(b"hello, world!")), b"aGVsbG8sIHdvcmxkIQ");
|
/// assert_eq!(bytes(b"hello, world!").encode(), b"aGVsbG8sIHdvcmxkIQ");
|
||||||
/// ```
|
/// ```
|
||||||
pub fn bytes(bytes: &[u8]) -> Term<'static> {
|
pub fn bytes(bytes: &[u8]) -> Term<'static> {
|
||||||
Term(T::OwnedStr(
|
Term(T::OwnedStr(
|
||||||
|
@ -176,7 +176,7 @@ impl<'a> Term<'a> {
|
||||||
/// ```
|
/// ```
|
||||||
/// use nettext::enc::*;
|
/// use nettext::enc::*;
|
||||||
///
|
///
|
||||||
/// assert_eq!(encode(list([string("hello").unwrap(), string("world").unwrap()]).unwrap().nested()), b"{ . = hello world }");
|
/// assert_eq!(list([string("hello").unwrap(), string("world").unwrap()]).unwrap().nested().encode(), b"{ . = hello world }");
|
||||||
/// ```
|
/// ```
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn nested(self) -> Term<'a> {
|
pub fn nested(self) -> Term<'a> {
|
||||||
|
@ -186,60 +186,64 @@ impl<'a> Term<'a> {
|
||||||
|
|
||||||
// ---- encoding function ----
|
// ---- encoding function ----
|
||||||
|
|
||||||
/// Generate the nettext representation of a term
|
impl<'a> Term<'a> {
|
||||||
pub fn encode(t: Term<'_>) -> Vec<u8> {
|
/// Generate the nettext representation of a term
|
||||||
let mut buf = Vec::with_capacity(128);
|
pub fn encode(self) -> Vec<u8> {
|
||||||
encode_aux(&mut buf, t.0, 0, true);
|
let mut buf = Vec::with_capacity(128);
|
||||||
buf
|
self.0.encode_aux(&mut buf, 0, true);
|
||||||
|
buf
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_aux(buf: &mut Vec<u8>, term: T<'_>, indent: usize, is_toplevel: bool) {
|
impl<'a> T<'a> {
|
||||||
match term {
|
fn encode_aux(self, buf: &mut Vec<u8>, indent: usize, is_toplevel: bool) {
|
||||||
T::Str(s) => buf.extend_from_slice(s),
|
match self {
|
||||||
T::OwnedStr(s) => buf.extend_from_slice(&s),
|
T::Str(s) => buf.extend_from_slice(s),
|
||||||
T::Dict(mut d) => {
|
T::OwnedStr(s) => buf.extend_from_slice(&s),
|
||||||
if d.is_empty() {
|
T::Dict(mut d) => {
|
||||||
buf.extend_from_slice(b"{}");
|
if d.is_empty() {
|
||||||
} else if d.len() == 1 {
|
buf.extend_from_slice(b"{}");
|
||||||
buf.extend_from_slice(b"{ ");
|
} else if d.len() == 1 {
|
||||||
let (k, v) = d.into_iter().next().unwrap();
|
buf.extend_from_slice(b"{ ");
|
||||||
buf.extend_from_slice(k);
|
let (k, v) = d.into_iter().next().unwrap();
|
||||||
buf.extend_from_slice(b" = ");
|
|
||||||
encode_aux(buf, v, indent + 2, false);
|
|
||||||
buf.extend_from_slice(b" }");
|
|
||||||
} else {
|
|
||||||
buf.extend_from_slice(b"{\n");
|
|
||||||
let indent2 = indent + 2;
|
|
||||||
let mut keys = d.keys().cloned().collect::<Vec<_>>();
|
|
||||||
keys.sort();
|
|
||||||
for k in keys {
|
|
||||||
let v = d.remove(k).unwrap();
|
|
||||||
for _ in 0..indent2 {
|
|
||||||
buf.push(b' ');
|
|
||||||
}
|
|
||||||
buf.extend_from_slice(k);
|
buf.extend_from_slice(k);
|
||||||
buf.extend_from_slice(b" = ");
|
buf.extend_from_slice(b" = ");
|
||||||
encode_aux(buf, v, indent2, false);
|
v.encode_aux(buf, indent + 2, false);
|
||||||
buf.extend_from_slice(b",\n");
|
buf.extend_from_slice(b" }");
|
||||||
}
|
} else {
|
||||||
for _ in 0..indent {
|
buf.extend_from_slice(b"{\n");
|
||||||
buf.push(b' ');
|
let indent2 = indent + 2;
|
||||||
}
|
let mut keys = d.keys().cloned().collect::<Vec<_>>();
|
||||||
buf.push(b'}');
|
keys.sort();
|
||||||
}
|
for k in keys {
|
||||||
}
|
let v = d.remove(k).unwrap();
|
||||||
T::List(l) => {
|
for _ in 0..indent2 {
|
||||||
let indent2 = indent + 2;
|
buf.push(b' ');
|
||||||
for (i, v) in l.into_iter().enumerate() {
|
}
|
||||||
if !is_toplevel && buf.iter().rev().take_while(|c| **c != b'\n').count() >= 70 {
|
buf.extend_from_slice(k);
|
||||||
buf.push(b'\n');
|
buf.extend_from_slice(b" = ");
|
||||||
for _ in 0..indent2 {
|
v.encode_aux(buf, indent2, false);
|
||||||
|
buf.extend_from_slice(b",\n");
|
||||||
|
}
|
||||||
|
for _ in 0..indent {
|
||||||
buf.push(b' ');
|
buf.push(b' ');
|
||||||
}
|
}
|
||||||
} else if i > 0 {
|
buf.push(b'}');
|
||||||
buf.push(b' ');
|
}
|
||||||
|
}
|
||||||
|
T::List(l) => {
|
||||||
|
let indent2 = indent + 2;
|
||||||
|
for (i, v) in l.into_iter().enumerate() {
|
||||||
|
if !is_toplevel && buf.iter().rev().take_while(|c| **c != b'\n').count() >= 70 {
|
||||||
|
buf.push(b'\n');
|
||||||
|
for _ in 0..indent2 {
|
||||||
|
buf.push(b' ');
|
||||||
|
}
|
||||||
|
} else if i > 0 {
|
||||||
|
buf.push(b' ');
|
||||||
|
}
|
||||||
|
v.encode_aux(buf, indent2, is_toplevel);
|
||||||
}
|
}
|
||||||
encode_aux(buf, v, indent2, is_toplevel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,7 +270,7 @@ mod tests {
|
||||||
from = jxx,
|
from = jxx,
|
||||||
subject = hello,
|
subject = hello,
|
||||||
}";
|
}";
|
||||||
let enc = encode(input);
|
let enc = input.encode();
|
||||||
eprintln!("{}", std::str::from_utf8(&enc).unwrap());
|
eprintln!("{}", std::str::from_utf8(&enc).unwrap());
|
||||||
eprintln!("{}", std::str::from_utf8(&expected[..]).unwrap());
|
eprintln!("{}", std::str::from_utf8(&expected[..]).unwrap());
|
||||||
assert_eq!(&enc, &expected[..]);
|
assert_eq!(&enc, &expected[..]);
|
||||||
|
@ -282,16 +286,15 @@ mod tests {
|
||||||
.is_err());
|
.is_err());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
encode(
|
list([
|
||||||
list([
|
string("a").unwrap(),
|
||||||
string("a").unwrap(),
|
string("b").unwrap(),
|
||||||
string("b").unwrap(),
|
list([string("c").unwrap(), string("d").unwrap()])
|
||||||
list([string("c").unwrap(), string("d").unwrap()])
|
.unwrap()
|
||||||
.unwrap()
|
.nested()
|
||||||
.nested()
|
])
|
||||||
])
|
.unwrap()
|
||||||
.unwrap()
|
.encode(),
|
||||||
),
|
|
||||||
b"a b { . = c d }"
|
b"a b { . = c d }"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
//! let keypair = crypto::generate_keypair();
|
//! let keypair = crypto::generate_keypair();
|
||||||
//!
|
//!
|
||||||
//! // Encode a fist object that represents a payload that will be hashed and signed
|
//! // Encode a fist object that represents a payload that will be hashed and signed
|
||||||
//! let text1 = encode(list([
|
//! let text1 = list([
|
||||||
//! string("CALL").unwrap(),
|
//! string("CALL").unwrap(),
|
||||||
//! string("myfunction").unwrap(),
|
//! string("myfunction").unwrap(),
|
||||||
//! dict([
|
//! dict([
|
||||||
|
@ -18,18 +18,18 @@
|
||||||
//! ("d", bytes_split(&((0..128u8).collect::<Vec<_>>()))),
|
//! ("d", bytes_split(&((0..128u8).collect::<Vec<_>>()))),
|
||||||
//! ]),
|
//! ]),
|
||||||
//! keypair.public.term().unwrap(),
|
//! keypair.public.term().unwrap(),
|
||||||
//! ]).unwrap());
|
//! ]).unwrap().encode();
|
||||||
//! eprintln!("{}", std::str::from_utf8(&text1).unwrap());
|
//! eprintln!("{}", std::str::from_utf8(&text1).unwrap());
|
||||||
//!
|
//!
|
||||||
//! let hash = crypto::Blake2Sum::compute(&text1);
|
//! let hash = crypto::Blake2Sum::compute(&text1);
|
||||||
//! let sign = keypair.sign(&text1);
|
//! let sign = keypair.sign(&text1);
|
||||||
//!
|
//!
|
||||||
//! // Encode a second object that represents the signed and hashed payload
|
//! // Encode a second object that represents the signed and hashed payload
|
||||||
//! let text2 = encode(dict([
|
//! let text2 = dict([
|
||||||
//! ("hash", hash.term().unwrap()),
|
//! ("hash", hash.term().unwrap()),
|
||||||
//! ("signature", sign.term().unwrap()),
|
//! ("signature", sign.term().unwrap()),
|
||||||
//! ("payload", raw(&text1).unwrap()),
|
//! ("payload", raw(&text1).unwrap()),
|
||||||
//! ]));
|
//! ]).encode();
|
||||||
//! eprintln!("{}", std::str::from_utf8(&text2).unwrap());
|
//! eprintln!("{}", std::str::from_utf8(&text2).unwrap());
|
||||||
//!
|
//!
|
||||||
//! // Decode and check everything is fine
|
//! // Decode and check everything is fine
|
||||||
|
|
Loading…
Reference in a new issue