71 lines
1.8 KiB
Rust
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
|
|
}
|
|
}
|