use rmp_serde::{Serializer, config::BytesMode, encode::Error};
#[repr(transparent)]
struct FallibleWriter(Vec<u8>);
impl std::io::Write for FallibleWriter {
#[inline(always)]
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.write_all(buf)?;
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
#[inline]
fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
self.0
.try_reserve(buf.len())
.map_err(|_| std::io::ErrorKind::OutOfMemory)?;
self.0.extend_from_slice(buf);
Ok(())
}
}
pub fn to_vec_named<T>(val: &T) -> Result<Vec<u8>, Error>
where
T: serde::Serialize,
{
let mut wr = FallibleWriter(Vec::new());
hack_write_named(&mut wr, val)?;
Ok(wr.0)
}
fn hack_write_named<W, T>(wr: &mut W, val: &T) -> Result<(), Error>
where
W: std::io::Write + ?Sized,
T: serde::Serialize + ?Sized,
{
let se = Serializer::new(wr);
let se = se.with_struct_map();
let mut se = se.with_bytes(BytesMode::ForceIterables);
val.serialize(&mut se)
}