blob: 9969b731bd0d8e5906d40220f3c7102d48f264b0 [file] [log] [blame] [edit]
use std::borrow::Cow;
use std::fmt::{self, Debug, Formatter};
#[cfg(feature = "serialize")]
use serde::de::{Deserialize, Deserializer, Error, Visitor};
#[cfg(feature = "serialize")]
use serde::ser::{Serialize, Serializer};
pub fn write_cow_string(f: &mut Formatter, cow_string: &Cow<[u8]>) -> fmt::Result {
match cow_string {
Cow::Owned(s) => {
write!(f, "Owned(")?;
write_byte_string(f, &s)?;
}
Cow::Borrowed(s) => {
write!(f, "Borrowed(")?;
write_byte_string(f, s)?;
}
}
write!(f, ")")
}
pub fn write_byte_string(f: &mut Formatter, byte_string: &[u8]) -> fmt::Result {
write!(f, "\"")?;
for b in byte_string {
match *b {
32..=33 | 35..=126 => write!(f, "{}", *b as char)?,
34 => write!(f, "\\\"")?,
_ => write!(f, "{:#02X}", b)?,
}
}
write!(f, "\"")?;
Ok(())
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// Wrapper around `Vec<u8>` that has a human-readable debug representation:
/// printable ASCII symbols output as is, all other output in HEX notation.
///
/// Also, when `serialize` feature is on, this type deserialized using
/// [`deserialize_byte_buf`](serde::Deserializer::deserialize_byte_buf) instead
/// of vector's generic [`deserialize_seq`](serde::Deserializer::deserialize_seq)
#[derive(PartialEq, Eq)]
pub struct ByteBuf(pub Vec<u8>);
impl Debug for ByteBuf {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write_byte_string(f, &self.0)
}
}
#[cfg(feature = "serialize")]
impl<'de> Deserialize<'de> for ByteBuf {
fn deserialize<D>(d: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct ValueVisitor;
impl<'de> Visitor<'de> for ValueVisitor {
type Value = ByteBuf;
fn expecting(&self, f: &mut Formatter) -> fmt::Result {
f.write_str("byte data")
}
fn visit_bytes<E: Error>(self, v: &[u8]) -> Result<Self::Value, E> {
Ok(ByteBuf(v.to_vec()))
}
fn visit_byte_buf<E: Error>(self, v: Vec<u8>) -> Result<Self::Value, E> {
Ok(ByteBuf(v))
}
}
d.deserialize_byte_buf(ValueVisitor)
}
}
#[cfg(feature = "serialize")]
impl Serialize for ByteBuf {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_bytes(&self.0)
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// Wrapper around `&[u8]` that has a human-readable debug representation:
/// printable ASCII symbols output as is, all other output in HEX notation.
///
/// Also, when `serialize` feature is on, this type deserialized using
/// [`deserialize_bytes`](serde::Deserializer::deserialize_bytes) instead
/// of vector's generic [`deserialize_seq`](serde::Deserializer::deserialize_seq)
#[derive(PartialEq, Eq)]
pub struct Bytes<'de>(pub &'de [u8]);
impl<'de> Debug for Bytes<'de> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write_byte_string(f, self.0)
}
}
#[cfg(feature = "serialize")]
impl<'de> Deserialize<'de> for Bytes<'de> {
fn deserialize<D>(d: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct ValueVisitor;
impl<'de> Visitor<'de> for ValueVisitor {
type Value = Bytes<'de>;
fn expecting(&self, f: &mut Formatter) -> fmt::Result {
f.write_str("borrowed bytes")
}
fn visit_borrowed_bytes<E: Error>(self, v: &'de [u8]) -> Result<Self::Value, E> {
Ok(Bytes(v))
}
}
d.deserialize_bytes(ValueVisitor)
}
}
#[cfg(feature = "serialize")]
impl<'de> Serialize for Bytes<'de> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_bytes(self.0)
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
#[cfg(test)]
mod tests {
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn write_byte_string0() {
let bytes = ByteBuf(vec![10, 32, 32, 32, 32, 32, 32, 32, 32]);
assert_eq!(format!("{:?}", bytes), "\"0xA \"".to_owned());
}
#[test]
fn write_byte_string1() {
let bytes = ByteBuf(vec![
104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 119, 51, 46, 111, 114, 103, 47, 50,
48, 48, 50, 47, 48, 55, 47, 111, 119, 108, 35,
]);
assert_eq!(
format!("{:?}", bytes),
r##""http://www.w3.org/2002/07/owl#""##.to_owned()
);
}
#[test]
fn write_byte_string3() {
let bytes = ByteBuf(vec![
67, 108, 97, 115, 115, 32, 73, 82, 73, 61, 34, 35, 66, 34,
]);
assert_eq!(format!("{:?}", bytes), r##""Class IRI=\"#B\"""##.to_owned());
}
}