mod cbor;
mod json;
pub use self::cbor::CborSink;
pub use self::json::JsonSink;
use alloc::vec::Vec;
use crate::de::{DecodeConfig, Decoder, Token};
use crate::encoding::EncodeConfig;
use crate::error::{Error, Result};
use crate::number::Number;
use crate::write::Write;
pub trait EventSink {
fn null(&mut self) -> Result<()>;
fn boolean(&mut self, value: bool) -> Result<()>;
fn number(&mut self, value: Number) -> Result<()>;
fn string(&mut self, value: &str) -> Result<()>;
fn begin_array(&mut self) -> Result<()>;
fn end_array(&mut self) -> Result<()>;
fn begin_object(&mut self) -> Result<()>;
fn object_key(&mut self, key: &str) -> Result<()>;
fn end_object(&mut self) -> Result<()>;
}
pub fn json_into<S: EventSink + ?Sized>(input: &[u8], sink: &mut S) -> Result<()> {
json_into_with_config(input, DecodeConfig::default(), sink)
}
pub fn json_into_with_config<S: EventSink + ?Sized>(
input: &[u8],
config: DecodeConfig,
sink: &mut S,
) -> Result<()> {
let mut decoder = Decoder::with_config(input, config);
relay_json_value(&mut decoder, sink)?;
decoder.end()
}
pub fn cbor_into<S: EventSink + ?Sized>(input: &[u8], sink: &mut S) -> Result<()> {
cbor::cbor_into_with_max_depth(input, 128, sink)
}
pub fn cbor_into_with_max_depth<S: EventSink + ?Sized>(
input: &[u8],
max_depth: u32,
sink: &mut S,
) -> Result<()> {
cbor::cbor_into_with_max_depth(input, max_depth, sink)
}
pub fn json_to_cbor(input: &[u8]) -> Result<Vec<u8>> {
let mut sink = CborSink::new(Vec::new());
json_into(input, &mut sink)?;
sink.finish()
}
pub fn json_to_cbor_writer<W: Write>(input: &[u8], writer: W) -> Result<()> {
let mut sink = CborSink::new(writer);
json_into(input, &mut sink)?;
sink.finish().map(|_| ())
}
pub fn cbor_to_json(input: &[u8]) -> Result<Vec<u8>> {
cbor_to_json_with_config(input, EncodeConfig::compact())
}
pub fn cbor_to_json_pretty(input: &[u8]) -> Result<Vec<u8>> {
cbor_to_json_with_config(input, EncodeConfig::pretty())
}
pub fn cbor_to_json_with_config(input: &[u8], config: EncodeConfig) -> Result<Vec<u8>> {
let mut sink = JsonSink::with_config(Vec::new(), config);
cbor_into(input, &mut sink)?;
sink.finish()
}
pub fn cbor_to_json_writer<W: Write>(input: &[u8], writer: W) -> Result<()> {
let mut sink = JsonSink::new(writer);
cbor_into(input, &mut sink)?;
sink.finish().map(|_| ())
}
fn relay_json_value<'de, S: EventSink + ?Sized>(
decoder: &mut Decoder<'de>,
sink: &mut S,
) -> Result<()> {
match decoder.peek_token()? {
Token::Null => {
decoder.unit()?;
sink.null()
}
Token::Bool(_) => sink.boolean(decoder.bool()?),
Token::Number(_) => sink.number(decoder.number()?),
Token::Str(_) => {
let value = decoder.string()?;
sink.string(value.as_ref())
}
Token::BeginArray => {
decoder.begin_array()?;
sink.begin_array()?;
while decoder.array_has_more()? {
relay_json_value(decoder, sink)?;
if !decoder.array_entry_sep()? {
break;
}
}
decoder.end_array()?;
sink.end_array()
}
Token::BeginObject => {
decoder.begin_object()?;
sink.begin_object()?;
while let Some(key) = decoder.object_key()? {
sink.object_key(key.as_ref())?;
relay_json_value(decoder, sink)?;
if !decoder.object_entry_sep()? {
break;
}
}
decoder.end_object()?;
sink.end_object()
}
Token::EndArray | Token::EndObject => Err(Error::custom("unexpected container end")),
}
}
#[derive(Clone, Copy, PartialEq)]
pub(crate) enum ContainerKind {
Array,
Object,
}
enum Frame {
Array,
Object { expecting_value: bool },
}
pub(crate) enum ValuePosition {
Root,
Array,
Object,
}
pub(crate) struct StructureState {
frames: Vec<Frame>,
root_written: bool,
}
impl StructureState {
pub(crate) fn new() -> Self {
StructureState {
frames: Vec::new(),
root_written: false,
}
}
pub(crate) fn value(&mut self) -> Result<ValuePosition> {
match self.frames.last_mut() {
Some(Frame::Array) => Ok(ValuePosition::Array),
Some(Frame::Object { expecting_value }) if *expecting_value => {
*expecting_value = false;
Ok(ValuePosition::Object)
}
Some(Frame::Object { .. }) => Err(Error::custom("object key required before value")),
None if self.root_written => Err(Error::custom("multiple root values")),
None => {
self.root_written = true;
Ok(ValuePosition::Root)
}
}
}
pub(crate) fn begin(&mut self, kind: ContainerKind) -> Result<ValuePosition> {
let position = self.value()?;
self.frames.push(match kind {
ContainerKind::Array => Frame::Array,
ContainerKind::Object => Frame::Object {
expecting_value: false,
},
});
Ok(position)
}
pub(crate) fn key(&mut self) -> Result<()> {
match self.frames.last_mut() {
Some(Frame::Object { expecting_value }) if !*expecting_value => {
*expecting_value = true;
Ok(())
}
Some(Frame::Object { .. }) => Err(Error::custom("object value required after key")),
_ => Err(Error::custom("object key outside object")),
}
}
pub(crate) fn end(&mut self, kind: ContainerKind) -> Result<()> {
let frame = self
.frames
.pop()
.ok_or_else(|| Error::custom("container end without matching start"))?;
match (kind, frame) {
(ContainerKind::Array, Frame::Array) => Ok(()),
(
ContainerKind::Object,
Frame::Object {
expecting_value: false,
},
) => Ok(()),
(
ContainerKind::Object,
Frame::Object {
expecting_value: true,
},
) => Err(Error::custom("object ended before keyed value")),
_ => Err(Error::custom("mismatched container end")),
}
}
pub(crate) fn finish(&self) -> Result<()> {
if !self.root_written {
return Err(Error::custom("event stream did not contain a root value"));
}
if !self.frames.is_empty() {
return Err(Error::custom("event stream ended inside a container"));
}
Ok(())
}
}