use std::ffi::CStr; mod cstr_as_bytes { use std::ffi::CStr; use serde::{Serializer, Deserializer, Deserialize}; pub fn serialize(s: &CStr, ser: S) -> Result where S: Serializer { ser.serialize_bytes(s.to_bytes_with_nul()) } pub fn deserialize<'de, D>(de: D) -> Result<&'de CStr, D::Error> where D: Deserializer<'de> { use serde::de::Error; let b = <&'de [u8]>::deserialize(de)?; CStr::from_bytes_with_nul(b) .map_err(|_| D::Error::invalid_value(serde::de::Unexpected::Bytes(b), &"a sequence of bytes ending with NUL")) } } #[derive(Debug, Clone, Copy, Serialize, Deserialize)] #[serde(transparent)] pub struct ByteSlice<'a>(#[serde(serialize_with = "serialize_bytes")] &'a [u8]); pub fn serialize_bytes(b: &[u8], ser: S) -> Result where S: serde::Serializer { ser.serialize_bytes(b) } impl<'a> std::ops::Deref for ByteSlice<'a> { type Target = [u8]; fn deref(&self) -> &Self::Target { self.0 } } impl<'a> From<&'a [u8]> for ByteSlice<'a> { fn from(value: &'a [u8]) -> Self { Self(value) } } impl<'a> From> for &'a [u8] { fn from(value: ByteSlice<'a>) -> Self { value.0 } } #[derive(Debug, Clone, Copy, Serialize, Deserialize)] #[serde(transparent)] pub struct CStrAsBytes<'a>(#[serde(serialize_with = "cstr_as_bytes::serialize", deserialize_with = "cstr_as_bytes::deserialize", borrow)] &'a CStr); impl<'a> std::ops::Deref for CStrAsBytes<'a> { type Target = CStr; fn deref(&self) -> &Self::Target { self.0 } } impl<'a> From<&'a CStr> for CStrAsBytes<'a> { fn from(value: &'a CStr) -> Self { Self(value) } } impl<'a> From> for &'a CStr { fn from(value: CStrAsBytes<'a>) -> Self { value.0 } }