use std::borrow::{Borrow, Cow};
use std::fmt::{self, Debug, Formatter};
use std::ops::Deref;
#[cfg(feature = "serialize")]
use serde::de::{Deserialize, Deserializer, Error, Visitor};
#[cfg(feature = "serialize")]
use serde::ser::{Serialize, Serializer};
#[allow(clippy::ptr_arg)]
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(())
}
pub enum CowRef<'i, 's, B>
where
B: ToOwned + ?Sized,
{
Input(&'i B),
Slice(&'s B),
Owned(<B as ToOwned>::Owned),
}
impl<'i, 's, B> Deref for CowRef<'i, 's, B>
where
B: ToOwned + ?Sized,
B::Owned: Borrow<B>,
{
type Target = B;
fn deref(&self) -> &B {
match *self {
Self::Input(borrowed) => borrowed,
Self::Slice(borrowed) => borrowed,
Self::Owned(ref owned) => owned.borrow(),
}
}
}
impl<'i, 's, B> Debug for CowRef<'i, 's, B>
where
B: ToOwned + ?Sized + Debug,
B::Owned: Debug,
{
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match *self {
Self::Input(borrowed) => Debug::fmt(borrowed, f),
Self::Slice(borrowed) => Debug::fmt(borrowed, f),
Self::Owned(ref owned) => Debug::fmt(owned, f),
}
}
}
#[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)
}
}
#[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 \"");
}
#[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#""##
);
}
#[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\"""##);
}
}