#![no_std]
#[cfg(test)]
extern crate self as zerompk;
#[macro_use]
mod read_macro;
#[macro_use]
mod write_macro;
#[cfg(feature = "std")]
mod bufread;
mod consts;
mod error;
mod r#impl;
mod read;
mod value;
mod write;
use alloc::vec::Vec;
pub use error::{Error, Result};
pub use read::{Read, SliceReader, Tag};
pub use value::Value;
pub use write::Write;
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "derive")]
pub use zerompk_derive::{FromMessagePack, ToMessagePack};
pub trait FromMessagePack<'a>
where
Self: Sized,
{
fn read<R: Read<'a>>(reader: &mut R) -> Result<Self>;
}
pub trait FromMessagePackOwned: for<'a> FromMessagePack<'a> {}
impl<T> FromMessagePackOwned for T where T: for<'a> FromMessagePack<'a> {}
pub struct TrustedSizeHint(usize);
impl TrustedSizeHint {
#[doc(hidden)]
#[inline(always)]
pub const unsafe fn new_unchecked(upper_bound: usize) -> Self {
Self(upper_bound)
}
#[inline(always)]
pub const fn upper_bound(&self) -> usize {
self.0
}
}
pub trait ToMessagePack {
fn write<W: Write>(&self, writer: &mut W) -> Result<()>;
#[inline(always)]
fn write_slice<W: Write>(values: &[Self], writer: &mut W) -> Result<()>
where
Self: Sized,
{
for value in values {
value.write(writer)?;
}
Ok(())
}
#[inline]
fn size_hint(&self) -> Option<TrustedSizeHint> {
None
}
#[inline]
fn max_size() -> Option<TrustedSizeHint>
where
Self: Sized,
{
None
}
}
pub fn from_msgpack<'a, T: FromMessagePack<'a>>(data: &'a [u8]) -> Result<T> {
let mut reader = read::SliceReader::new(data);
T::read(&mut reader)
}
pub fn to_msgpack_vec<T: ToMessagePack>(value: &T) -> Result<Vec<u8>> {
const MAX_SIZE_HINT_PREALLOC: usize = 16 * 1024 * 1024;
let mut writer = match value.size_hint() {
Some(hint) => {
write::VecWriter::with_capacity_hint(hint.upper_bound().min(MAX_SIZE_HINT_PREALLOC))
}
None => write::VecWriter::new(),
};
value.write(&mut writer)?;
Ok(writer.into_vec())
}
pub fn to_msgpack<T: ToMessagePack>(value: &T, buf: &mut [u8]) -> Result<usize> {
if let Some(hint) = value.size_hint()
&& hint.upper_bound() <= buf.len()
{
let mut writer = unsafe { write::SliceWriter::new_unchecked(buf) };
value.write(&mut writer)?;
debug_assert!(writer.position() <= hint.upper_bound());
return Ok(writer.position());
}
to_msgpack_checked(value, buf)
}
#[cold]
#[inline(never)]
fn to_msgpack_checked<T: ToMessagePack>(value: &T, buf: &mut [u8]) -> Result<usize> {
let mut writer = write::SliceWriter::new(buf);
value.write(&mut writer)?;
Ok(writer.position())
}
#[cfg(feature = "std")]
pub fn write_msgpack<T: ToMessagePack, W: std::io::Write>(writer: &mut W, value: &T) -> Result<()> {
let mut io_writer = write::IOWriter::new(writer);
value.write(&mut io_writer)
}
#[cfg(feature = "std")]
pub fn read_msgpack<'a, R: std::io::Read, T: FromMessagePack<'a>>(reader: R) -> Result<T> {
let mut io_reader = read::IOReader::new(reader);
T::read(&mut io_reader)
}
#[cfg(feature = "std")]
pub fn read_msgpack_bufread<'a, R: std::io::BufRead, T: FromMessagePack<'a>>(
reader: &mut R,
) -> Result<T> {
let mut bufread_reader = bufread::BufReadReader::new(reader);
T::read(&mut bufread_reader)
}