quinoa/src/ser.rs

71 lines
1.8 KiB
Rust

use std::ffi::CStr;
mod cstr_as_bytes {
use std::ffi::CStr;
use serde::{Serializer, Deserializer, Deserialize};
pub fn serialize<S>(s: &CStr, ser: S) -> Result<S::Ok, S::Error> 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<S>(b: &[u8], ser: S) -> Result<S::Ok, S::Error> 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<ByteSlice<'a>> 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<CStrAsBytes<'a>> for &'a CStr {
fn from(value: CStrAsBytes<'a>) -> Self {
value.0
}
}