Cleanup
This commit is contained in:
parent
24c7a9bbb5
commit
7a79994b00
7 changed files with 73 additions and 211 deletions
|
@ -5,7 +5,9 @@ mod error;
|
|||
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[cfg(any(feature = "blake2", feature = "ed25519-dalek"))]
|
||||
use crate::crypto;
|
||||
|
||||
pub use decode::*;
|
||||
pub use error::*;
|
||||
|
||||
|
@ -578,16 +580,6 @@ impl<'a, 'b> std::fmt::Debug for AnyTerm<'a, 'b> {
|
|||
|
||||
impl<'a, 'b> std::fmt::Debug for NonListTerm<'a, 'b> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
||||
match self.mkref() {
|
||||
NonListTerm::Str(s) => write!(f, "Str(`{}`)", debug(s)),
|
||||
NonListTerm::DictRef(raw, d) => {
|
||||
write!(f, "Dict<`{}`", debug(raw))?;
|
||||
for (k, v) in d.iter() {
|
||||
write!(f, "\n `{}`={:?}", debug(k), v)?;
|
||||
}
|
||||
write!(f, ">")
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
AnyTerm::from(self.mkref()).fmt(f)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ pub enum Error {
|
|||
InvalidCharacter(u8),
|
||||
InvalidRaw,
|
||||
NotADictionnary,
|
||||
DuplicateKey(String),
|
||||
ListInList,
|
||||
}
|
||||
|
||||
|
@ -15,6 +16,7 @@ impl std::fmt::Display for Error {
|
|||
Error::InvalidCharacter(c) => write!(f, "Invalid character '{}'", *c as char),
|
||||
Error::InvalidRaw => write!(f, "Invalid RAW nettext litteral"),
|
||||
Error::NotADictionnary => write!(f, "Tried to insert into a term that isn't a dictionnary"),
|
||||
Error::DuplicateKey(s) => write!(f, "Duplicate dict key: {}", s),
|
||||
Error::ListInList => write!(f, "Refusing to build nested lists with list(), use either list_flatten() or list_nested()"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
//! ("b", string("world").unwrap()),
|
||||
//! ("c", raw(b"{ a = 12, b = 42 }").unwrap()),
|
||||
//! ("d", bytes_split(&((0..128u8).collect::<Vec<_>>()))),
|
||||
//! ]),
|
||||
//! ]).unwrap(),
|
||||
//! ]).unwrap().encode();
|
||||
//! ```
|
||||
|
||||
|
@ -94,13 +94,6 @@ pub fn raw(bytes: &[u8]) -> Result<'_> {
|
|||
Ok(Term(T::Str(bytes)))
|
||||
}
|
||||
|
||||
pub(crate) fn safe_raw(bytes: &[u8]) -> Term<'_> {
|
||||
Term(T::Str(bytes))
|
||||
}
|
||||
pub(crate) fn safe_raw_owned(bytes: Vec<u8>) -> Term<'static> {
|
||||
Term(T::OwnedStr(bytes))
|
||||
}
|
||||
|
||||
/// Term corresponding to a list of terms
|
||||
///
|
||||
/// ```
|
||||
|
@ -154,22 +147,16 @@ pub fn list_nested<'a, I: IntoIterator<Item = Term<'a>>>(terms: I) -> Result<'a>
|
|||
/// assert_eq!(dict([
|
||||
/// ("a", string("Hello").unwrap()),
|
||||
/// ("b", string("world").unwrap())
|
||||
/// ]).encode(), b"{\n a = Hello,\n b = world,\n}");
|
||||
/// ]).unwrap().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) -> Result<'a> {
|
||||
let mut tmp = HashMap::new();
|
||||
for (k, v) in pairs {
|
||||
tmp.insert(Cow::from(k.as_bytes()), v.0);
|
||||
if tmp.insert(Cow::from(k.as_bytes()), v.0).is_some() {
|
||||
return Err(Error::DuplicateKey(k.to_string()));
|
||||
}
|
||||
}
|
||||
Term(T::Dict(tmp))
|
||||
}
|
||||
|
||||
pub(crate) fn dict_owned_u8<'a, I: IntoIterator<Item = (Vec<u8>, Term<'a>)>>(pairs: I) -> Term<'a> {
|
||||
let mut tmp = HashMap::new();
|
||||
for (k, v) in pairs {
|
||||
tmp.insert(Cow::from(k), v.0);
|
||||
}
|
||||
Term(T::Dict(tmp))
|
||||
Ok(Term(T::Dict(tmp)))
|
||||
}
|
||||
|
||||
/// Term corresponding to a byte slice,
|
||||
|
@ -223,7 +210,9 @@ impl<'a> Term<'a> {
|
|||
pub fn insert(self, k: &'a str, v: Term<'a>) -> Result<'a> {
|
||||
match self.0 {
|
||||
T::Dict(mut d) => {
|
||||
d.insert(Cow::from(k.as_bytes()), v.0);
|
||||
if d.insert(Cow::from(k.as_bytes()), v.0).is_some() {
|
||||
return Err(Error::DuplicateKey(k.to_string()));
|
||||
}
|
||||
Ok(Term(T::Dict(d)))
|
||||
}
|
||||
_ => Err(Error::NotADictionnary),
|
||||
|
@ -242,10 +231,33 @@ impl<'a> Term<'a> {
|
|||
/// ```
|
||||
#[must_use]
|
||||
pub fn nested(self) -> Term<'a> {
|
||||
dict([(".", self)])
|
||||
dict([(".", self)]).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// ---- additional internal functions for serde module ----
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
pub(crate) fn dict_owned_u8<'a, I: IntoIterator<Item = (Vec<u8>, Term<'a>)>>(
|
||||
pairs: I,
|
||||
) -> Result<'a> {
|
||||
let mut tmp = HashMap::new();
|
||||
for (k, v) in pairs {
|
||||
tmp.insert(Cow::from(k), v.0);
|
||||
}
|
||||
Ok(Term(T::Dict(tmp)))
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
pub(crate) fn safe_raw(bytes: &[u8]) -> Term<'_> {
|
||||
Term(T::Str(bytes))
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
pub(crate) fn safe_raw_owned(bytes: Vec<u8>) -> Term<'static> {
|
||||
Term(T::OwnedStr(bytes))
|
||||
}
|
||||
|
||||
// ---- encoding function ----
|
||||
|
||||
impl<'a> Term<'a> {
|
||||
|
@ -267,13 +279,13 @@ impl<'a> T<'a> {
|
|||
buf.extend_from_slice(b"{}");
|
||||
} else if d.len() == 1 {
|
||||
let (k, v) = d.into_iter().next().unwrap();
|
||||
if k.as_ref() == b"." {
|
||||
buf.extend_from_slice(b"{.= ");
|
||||
} else {
|
||||
buf.extend_from_slice(b"{ ");
|
||||
buf.extend_from_slice(k.borrow());
|
||||
buf.extend_from_slice(b" = ");
|
||||
}
|
||||
if k.as_ref() == b"." {
|
||||
buf.extend_from_slice(b"{.= ");
|
||||
} else {
|
||||
buf.extend_from_slice(b"{ ");
|
||||
buf.extend_from_slice(k.borrow());
|
||||
buf.extend_from_slice(b" = ");
|
||||
}
|
||||
v.encode_aux(buf, indent + 2, false);
|
||||
buf.extend_from_slice(b" }");
|
||||
} else {
|
||||
|
@ -328,7 +340,8 @@ mod tests {
|
|||
("from", string("jxx").unwrap()),
|
||||
("subject", string("hello").unwrap()),
|
||||
("data", raw(b"{ f1 = plop, f2 = kuko }").unwrap()),
|
||||
]),
|
||||
])
|
||||
.unwrap(),
|
||||
])
|
||||
.unwrap();
|
||||
let expected = b"HELLO alexhelloworld {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
//! ("b", string("world").unwrap()),
|
||||
//! ("c", raw(b"{ a = 12, b = 42 }").unwrap()),
|
||||
//! ("d", bytes_split(&((0..128u8).collect::<Vec<_>>()))),
|
||||
//! ]),
|
||||
//! ]).unwrap(),
|
||||
//! keypair.public.term().unwrap(),
|
||||
//! ]).unwrap().encode();
|
||||
//! eprintln!("{}", std::str::from_utf8(&text1).unwrap());
|
||||
|
@ -29,7 +29,7 @@
|
|||
//! ("hash", hash.term().unwrap()),
|
||||
//! ("signature", sign.term().unwrap()),
|
||||
//! ("payload", raw(&text1).unwrap()),
|
||||
//! ]).encode();
|
||||
//! ]).unwrap().encode();
|
||||
//! eprintln!("{}", std::str::from_utf8(&text2).unwrap());
|
||||
//!
|
||||
//! // Decode and check everything is fine
|
||||
|
|
|
@ -40,7 +40,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de, 'a> {
|
|||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
Err(Error::custom("derialize_any not supported"))
|
||||
Err(Error::custom(format!(
|
||||
"deserialize_any not supported, at: `{}`",
|
||||
self.0
|
||||
)))
|
||||
}
|
||||
|
||||
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
|
||||
|
@ -400,9 +403,9 @@ impl<'de, 'a> EnumAccess<'de> for Enum<'de, 'a> {
|
|||
where
|
||||
V: DeserializeSeed<'de>,
|
||||
{
|
||||
let term = &self.0.list()[0];
|
||||
let value = seed.deserialize(&mut Deserializer(Term(term.0.mkref())))?;
|
||||
Ok((value, self))
|
||||
let variant = &self.0.list()[0];
|
||||
let variant = seed.deserialize(&mut Deserializer(Term(variant.0.mkref())))?;
|
||||
Ok((variant, self))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -441,57 +444,3 @@ impl<'de, 'a> VariantAccess<'de> for Enum<'de, 'a> {
|
|||
visitor.visit_map(&mut Dict::from_term(&rest)?)
|
||||
}
|
||||
}
|
||||
|
||||
// ----
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_struct() {
|
||||
#[derive(Deserialize, PartialEq, Debug)]
|
||||
struct Test {
|
||||
int: u32,
|
||||
seq: Vec<String>,
|
||||
}
|
||||
|
||||
let nt = br#"Test { int = 1, seq = YQ Yg }"#;
|
||||
let expected = Test {
|
||||
int: 1,
|
||||
seq: vec!["a".to_owned(), "b".to_owned()],
|
||||
};
|
||||
assert_eq!(expected, from_bytes(nt).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_enum() {
|
||||
#[derive(Deserialize, PartialEq, Debug)]
|
||||
enum E {
|
||||
Unit,
|
||||
Newtype(u32),
|
||||
Tuple(u32, u32),
|
||||
Struct { a: u32 },
|
||||
}
|
||||
|
||||
let nt = br#"E.Unit"#;
|
||||
let expected = E::Unit;
|
||||
assert_eq!(expected, from_bytes(nt).unwrap());
|
||||
eprintln!("UNIT OK");
|
||||
|
||||
let nt = br#"E.Newtype 1"#;
|
||||
let expected = E::Newtype(1);
|
||||
assert_eq!(expected, from_bytes(nt).unwrap());
|
||||
eprintln!("NEWTYPE OK");
|
||||
|
||||
let nt = br#"E.Tuple 1 2"#;
|
||||
let expected = E::Tuple(1, 2);
|
||||
assert_eq!(expected, from_bytes(nt).unwrap());
|
||||
eprintln!("TUPLE OK");
|
||||
|
||||
let nt = br#"E.Struct { a = 1 }"#;
|
||||
let expected = E::Struct { a: 1 };
|
||||
assert_eq!(expected, from_bytes(nt).unwrap());
|
||||
eprintln!("STRUCT OK");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,15 +41,15 @@ mod tests {
|
|||
test_bidir(input, expected);
|
||||
|
||||
let input = vec![
|
||||
Test {
|
||||
int: 1,
|
||||
seq: vec!["a".to_string(), "b".to_string()],
|
||||
},
|
||||
Test {
|
||||
int: 2,
|
||||
seq: vec!["c".to_string(), "d".to_string()],
|
||||
},
|
||||
];
|
||||
Test {
|
||||
int: 1,
|
||||
seq: vec!["a".to_string(), "b".to_string()],
|
||||
},
|
||||
Test {
|
||||
int: 2,
|
||||
seq: vec!["c".to_string(), "d".to_string()],
|
||||
},
|
||||
];
|
||||
let expected = br#"{.= Test {
|
||||
int = 1,
|
||||
seq = YQ Yg,
|
||||
|
@ -94,7 +94,8 @@ mod tests {
|
|||
E::Struct { a: 1 },
|
||||
E::Tuple(3, 2),
|
||||
];
|
||||
let expected = br#"E.Unit E.Unit {.= E.Newtype 1 } {.= E.Tuple 1 2 } {.= E.Struct { a = 1 } } {.=
|
||||
let expected =
|
||||
br#"E.Unit E.Unit {.= E.Newtype 1 } {.= E.Tuple 1 2 } {.= E.Struct { a = 1 } } {.=
|
||||
E.Tuple 3 2 }"#;
|
||||
test_bidir(input, expected);
|
||||
}
|
||||
|
|
105
src/serde/ser.rs
105
src/serde/ser.rs
|
@ -94,7 +94,7 @@ impl<'a> ser::Serializer for &'a mut Serializer {
|
|||
}
|
||||
|
||||
fn serialize_none(self) -> Result<Self::Ok> {
|
||||
Ok(dict([]))
|
||||
Ok(dict([])?)
|
||||
}
|
||||
|
||||
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok>
|
||||
|
@ -105,7 +105,7 @@ impl<'a> ser::Serializer for &'a mut Serializer {
|
|||
}
|
||||
|
||||
fn serialize_unit(self) -> Result<Self::Ok> {
|
||||
Ok(dict([]))
|
||||
Ok(dict([])?)
|
||||
}
|
||||
|
||||
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
|
||||
|
@ -309,7 +309,7 @@ impl ser::SerializeMap for MapSerializer {
|
|||
}
|
||||
|
||||
fn end(self) -> Result<Term<'static>> {
|
||||
Ok(dict_owned_u8(self.fields.into_iter()))
|
||||
Ok(dict_owned_u8(self.fields.into_iter())?)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -331,7 +331,7 @@ impl ser::SerializeStruct for StructSerializer {
|
|||
}
|
||||
|
||||
fn end(self) -> Result<Term<'static>> {
|
||||
Ok(list([string(self.name)?, dict(self.fields.into_iter())])?)
|
||||
Ok(list([string(self.name)?, dict(self.fields.into_iter())?])?)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -356,102 +356,7 @@ impl ser::SerializeStructVariant for StructVariantSerializer {
|
|||
fn end(self) -> Result<Term<'static>> {
|
||||
Ok(list([
|
||||
string_owned(format!("{}.{}", self.name, self.variant))?,
|
||||
dict(self.fields.into_iter()),
|
||||
dict(self.fields.into_iter())?,
|
||||
])?)
|
||||
}
|
||||
}
|
||||
|
||||
// ----
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde::Serialize;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[test]
|
||||
fn test_struct() {
|
||||
#[derive(Serialize)]
|
||||
struct Test {
|
||||
int: u32,
|
||||
seq: Vec<&'static str>,
|
||||
}
|
||||
|
||||
let test = Test {
|
||||
int: 1,
|
||||
seq: vec!["a", "b"],
|
||||
};
|
||||
let expected = br#"Test {
|
||||
int = 1,
|
||||
seq = YQ Yg,
|
||||
}"#;
|
||||
assert_eq!(&to_bytes(&test).unwrap(), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_enum() {
|
||||
#[derive(Serialize)]
|
||||
enum E {
|
||||
Unit,
|
||||
Newtype(u32),
|
||||
Tuple(u32, u32),
|
||||
Struct { a: u32 },
|
||||
}
|
||||
|
||||
let u = E::Unit;
|
||||
let expected = br#"E.Unit"#;
|
||||
assert_eq!(&to_bytes(&u).unwrap(), expected);
|
||||
|
||||
let n = E::Newtype(1);
|
||||
let expected = br#"E.Newtype 1"#;
|
||||
assert_eq!(&to_bytes(&n).unwrap(), expected);
|
||||
|
||||
let t = E::Tuple(1, 2);
|
||||
let expected = br#"E.Tuple 1 2"#;
|
||||
assert_eq!(&to_bytes(&t).unwrap(), expected);
|
||||
|
||||
let s = E::Struct { a: 1 };
|
||||
let expected = br#"E.Struct { a = 1 }"#;
|
||||
assert_eq!(&to_bytes(&s).unwrap(), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_seq() {
|
||||
let u = (1, 2, 3, 4);
|
||||
let expected = br#"1 2 3 4"#;
|
||||
assert_eq!(&to_bytes(&u).unwrap(), expected);
|
||||
|
||||
let n = (1, 2, (2, 3, 4), 5, 6);
|
||||
let expected = br#"1 2 {.= 2 3 4 } 5 6"#;
|
||||
assert_eq!(&to_bytes(&n).unwrap(), expected);
|
||||
|
||||
let t = [1, 2, 3, 4];
|
||||
let expected = br#"1 2 3 4"#;
|
||||
assert_eq!(&to_bytes(&t).unwrap(), expected);
|
||||
|
||||
let s = [[1, 2], [2, 3], [3, 4]];
|
||||
let expected = br#"{.= 1 2 } {.= 2 3 } {.= 3 4 }"#;
|
||||
assert_eq!(&to_bytes(&s).unwrap(), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dict() {
|
||||
let mut d = HashMap::new();
|
||||
d.insert("hello", "world");
|
||||
d.insert("dont", "panic");
|
||||
let expected = br#"{
|
||||
ZG9udA = cGFuaWM,
|
||||
aGVsbG8 = d29ybGQ,
|
||||
}"#;
|
||||
assert_eq!(&to_bytes(&d).unwrap(), expected);
|
||||
|
||||
let mut d = HashMap::new();
|
||||
d.insert(12, vec![42, 125]);
|
||||
d.insert(33, vec![19, 22, 21]);
|
||||
let expected = br#"{
|
||||
12 = 42 125,
|
||||
33 = 19 22 21,
|
||||
}"#;
|
||||
assert_eq!(&to_bytes(&d).unwrap(), expected);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue