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")),
}
}