use crate::budget::EnforcingPolicy;
use crate::live_events::LiveEvents;
use super::api::{ReaderSnippetContext, StrSnippetContext};
use super::{Cfg, Error, Events, Options, YamlDeserializer};
pub(crate) fn normalize_str_input(input: &str) -> &str {
input.strip_prefix('\u{FEFF}').unwrap_or(input)
}
pub(crate) fn run_with_document_scope<'de, R, F, W, P>(
src: &mut LiveEvents<'de>,
f: F,
wrap_err: W,
synthesized_null_should_be_eof: P,
) -> Result<R, Error>
where
F: FnOnce(&mut LiveEvents<'de>) -> Result<R, Error>,
W: Fn(Error, &LiveEvents<'de>) -> Error,
P: Fn(&Error) -> bool,
{
let value_res = crate::anchor_store::with_document_scope(|| {
crate::properties_redaction::with_interp_redaction_scope(|| f(src))
});
match value_res {
Ok(v) => Ok(v),
Err(e) => {
if src.synthesized_null_emitted() && synthesized_null_should_be_eof(&e) {
Err(wrap_err(
Error::eof().with_location(src.last_location()),
src,
))
} else {
Err(wrap_err(e, src))
}
}
}
}
pub(crate) fn deserialize_with_scope_and_null_policy<'de, R, F, W, P>(
src: &mut LiveEvents<'de>,
cfg: Cfg,
f: F,
wrap_err: W,
synthesized_null_should_be_eof: P,
) -> Result<R, Error>
where
for<'e> F: FnOnce(crate::Deserializer<'de, 'e>) -> Result<R, Error>,
W: Fn(Error, &LiveEvents<'de>) -> Error,
P: Fn(&Error) -> bool,
{
run_with_document_scope(
src,
|src| super::with_root_redaction(YamlDeserializer::new(src, cfg), f),
wrap_err,
synthesized_null_should_be_eof,
)
}
pub(crate) 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, &LiveEvents<'de>) -> Error,
{
deserialize_with_scope_and_null_policy(src, cfg, f, wrap_err, |_| true)
}
pub(crate) 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, &LiveEvents<'de>) -> Error,
{
match src.peek() {
Ok(Some(_)) => {
return Err(wrap_err(
Error::multiple_documents(multiple_docs_hint).with_location(src.last_location()),
src,
));
}
Ok(None) => {}
Err(e) => {
if src.seen_doc_end() {
} else {
return Err(wrap_err(e, src));
}
}
}
src.finish().map_err(|e| wrap_err(e, src))
}
#[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);
let snippet_ctx = StrSnippetContext::new(input, with_snippet, crop_radius);
let wrap_err = |e, src: &LiveEvents<'de>| snippet_ctx.attach_snippet(e, src);
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 with_snippet = options.with_snippet;
let crop_radius = options.crop_radius;
let cfg = Cfg::from_options(&options);
let (snippet_ctx, ring_handle) = ReaderSnippetContext::new(reader, with_snippet, crop_radius);
let mut src = LiveEvents::from_reader(ring_handle, options, EnforcingPolicy::AllContent);
let wrap_err = |e, src: &LiveEvents<'_>| snippet_ctx.attach_snippet(e, src);
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)
}