use crate::budget::EnforcingPolicy;
use crate::live_events::LiveEvents;
use super::{Cfg, Error, Events, Options, YamlDeserializer};
fn normalize_str_input(input: &str) -> &str {
input.strip_prefix('\u{FEFF}').unwrap_or(input)
}
fn deserialize_with_scope<'de, R, F, W>(
src: &mut LiveEvents<'de>,
cfg: Cfg,
f: F,
wrap_err: W,
) -> Result<R, Error>
where
for<'e> F: FnOnce(crate::Deserializer<'de, 'e>) -> Result<R, Error>,
W: Fn(Error) -> Error,
{
let value_res = crate::anchor_store::with_document_scope(|| f(YamlDeserializer::new(src, cfg)));
match value_res {
Ok(v) => Ok(v),
Err(e) => {
if src.synthesized_null_emitted() {
Err(wrap_err(Error::eof().with_location(src.last_location())))
} else {
Err(wrap_err(e))
}
}
}
}
fn enforce_single_document_and_finish<'de, W>(
src: &mut LiveEvents<'de>,
multiple_docs_hint: &'static str,
wrap_err: W,
) -> Result<(), Error>
where
W: Fn(Error) -> Error,
{
match src.peek() {
Ok(Some(_)) => {
return Err(wrap_err(
Error::multiple_documents(multiple_docs_hint).with_location(src.last_location()),
));
}
Ok(None) => {}
Err(e) => {
if src.seen_doc_end() {
} else {
return Err(wrap_err(e));
}
}
}
src.finish().map_err(wrap_err)
}
#[allow(deprecated)]
pub fn with_deserializer_from_str_with_options<'de, R, F>(
input: &'de str,
options: Options,
f: F,
) -> Result<R, Error>
where
for<'e> F: FnOnce(crate::Deserializer<'de, 'e>) -> Result<R, Error>,
{
let input = normalize_str_input(input);
let with_snippet = options.with_snippet;
let crop_radius = options.crop_radius;
let cfg = Cfg::from_options(&options);
let mut src = LiveEvents::from_str(
input,
options.budget,
options.budget_report,
options.budget_report_cb,
options.alias_limits,
false,
);
let wrap_err = |e| crate::maybe_with_snippet(e, input, with_snippet, crop_radius);
let value = deserialize_with_scope(&mut src, cfg, f, wrap_err)?;
enforce_single_document_and_finish(
&mut src,
"use from_multiple or from_multiple_with_options",
wrap_err,
)?;
Ok(value)
}
pub fn with_deserializer_from_str<'de, R, F>(input: &'de str, f: F) -> Result<R, Error>
where
for<'e> F: FnOnce(crate::Deserializer<'de, 'e>) -> Result<R, Error>,
{
with_deserializer_from_str_with_options(input, Options::default(), f)
}
pub fn with_deserializer_from_slice<'de, R, F>(bytes: &'de [u8], f: F) -> Result<R, Error>
where
for<'e> F: FnOnce(crate::Deserializer<'de, 'e>) -> Result<R, Error>,
{
with_deserializer_from_slice_with_options(bytes, Options::default(), f)
}
pub fn with_deserializer_from_slice_with_options<'de, R, F>(
bytes: &'de [u8],
options: Options,
f: F,
) -> Result<R, Error>
where
for<'e> F: FnOnce(crate::Deserializer<'de, 'e>) -> Result<R, Error>,
{
let s = std::str::from_utf8(bytes).map_err(|_| Error::InvalidUtf8Input)?;
with_deserializer_from_str_with_options(s, options, f)
}
pub fn with_deserializer_from_reader<R, Out, F>(reader: R, f: F) -> Result<Out, Error>
where
for<'de, 'e> F: FnOnce(crate::Deserializer<'de, 'e>) -> Result<Out, Error>,
R: std::io::Read,
{
with_deserializer_from_reader_with_options(reader, Options::default(), f)
}
#[allow(deprecated)]
pub fn with_deserializer_from_reader_with_options<R, Out, F>(
reader: R,
options: Options,
f: F,
) -> Result<Out, Error>
where
for<'de, 'e> F: FnOnce(crate::Deserializer<'de, 'e>) -> Result<Out, Error>,
R: std::io::Read,
{
let cfg = Cfg::from_options(&options);
let mut src = LiveEvents::from_reader(
reader,
options.budget,
options.budget_report,
options.budget_report_cb,
options.alias_limits,
false,
EnforcingPolicy::AllContent,
);
let wrap_err = |e| e;
let value = deserialize_with_scope(&mut src, cfg, f, wrap_err)?;
enforce_single_document_and_finish(
&mut src,
"use read or read_with_options to obtain the iterator",
wrap_err,
)?;
Ok(value)
}