#![no_std]
#![doc = include_str!("../README.md")]
#![cfg_attr(feature = "f16", feature(f16))]
#![warn(missing_docs)]
#![warn(rustdoc::broken_intra_doc_links)]
#[cfg(test)]
extern crate self as zerocbor;
mod consts;
mod error;
mod r#impl;
mod read;
mod value;
mod write;
use alloc::vec::Vec;
pub use consts::tags;
pub use error::{Error, Result};
pub use read::{ArrayIter, Len, MAX_DEPTH, MapIter, Read};
pub use value::Value;
pub use write::Write;
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "derive")]
pub use zerocbor_derive::{FromCbor, ToCbor};
pub trait FromCbor<'a>
where
Self: Sized,
{
fn read<R: Read<'a>>(reader: &mut R) -> Result<Self>;
}
pub trait FromCborOwned: for<'a> FromCbor<'a> {}
impl<T> FromCborOwned for T where T: for<'a> FromCbor<'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 ToCbor {
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 check_optional_tag(expected: Option<u64>, found: Option<u64>) -> Result<()> {
if expected == found {
return Ok(());
}
Err(match (expected, found) {
(Some(expected), Some(found)) => Error::TagMismatch {
expected,
found: Some(found),
},
(Some(expected), None) => Error::TagMismatch {
expected,
found: None,
},
(None, Some(found)) => Error::UnexpectedTag { found },
(None, None) => unreachable!("the options are equal"),
})
}
pub fn from_cbor<'a, T: FromCbor<'a>>(data: &'a [u8]) -> Result<T> {
let mut reader = read::SliceReader::new(data);
T::read(&mut reader)
}
pub fn to_cbor_vec<T: ToCbor + ?Sized>(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_cbor<T: ToCbor + ?Sized>(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_cbor<T: ToCbor + ?Sized, 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_cbor<'a, R: std::io::Read, T: FromCbor<'a>>(reader: R) -> Result<T> {
let mut io_reader = read::IOReader::new(reader);
T::read(&mut io_reader)
}