use std::borrow::Cow;
use std::collections::{HashMap, HashSet};
use std::marker::PhantomData;
use std::sync::Arc;
use deser_core::de::{self, Deserialize, DeserializeDriver, deserialize_value};
use deser_core::hints::Layout;
use deser_core::{Atom, Error, ErrorKind, Event, Implicit, ImplicitValue, Source, TrackLocations};
use crate::event::{Event as YamlEvent, EventKind, Mark, ScalarStyle};
use crate::parser::{Parser, error_at};
use crate::resolve::{ScalarTag, Version};
use crate::resolve::{
classify_tag, is_collection_tag, resolve_plain, resolve_plain_implicit, resolve_standard,
};
use crate::tag::NodeTag;
const DEFAULT_ALIAS_LIMIT: usize = 1_000_000;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DeserializerConfig {
version: Version,
alias_limit: usize,
merge_keys: bool,
context: deser_core::Context,
}
impl Default for DeserializerConfig {
fn default() -> DeserializerConfig {
DeserializerConfig::new()
}
}
impl DeserializerConfig {
pub const fn new() -> DeserializerConfig {
DeserializerConfig {
version: Version::V1_2,
alias_limit: DEFAULT_ALIAS_LIMIT,
merge_keys: true,
context: deser_core::Context::new(),
}
}
pub const fn builder() -> DeserializerConfigBuilder {
DeserializerConfigBuilder::new()
}
pub const fn into_builder(self) -> DeserializerConfigBuilder {
DeserializerConfigBuilder { value: self }
}
pub fn set_context(&mut self, context: deser_core::Context) {
self.context = context;
}
pub(crate) fn without_context(&self) -> DeserializerConfig {
let mut config = self.clone();
config.context = deser_core::Context::default();
config
}
pub fn context(&self) -> &deser_core::Context {
&self.context
}
pub const fn set_version(&mut self, version: Version) {
self.version = version;
}
pub const fn set_alias_limit(&mut self, limit: usize) {
self.alias_limit = limit;
}
pub const fn set_merge_keys(&mut self, yes: bool) {
self.merge_keys = yes;
}
pub fn from_str<'de, T: Deserialize<'de>>(&self, s: &'de str) -> Result<T, Error> {
deserialize_value(|driver| self.drive_str(s, driver))
}
fn drive_str<'de>(
&self,
s: &'de str,
driver: &mut DeserializeDriver<'_, 'de>,
) -> Result<(), Error> {
drive_single(Deserializer::from_str_with_config(s, self.clone()), driver)
}
pub fn from_slice<'de, T: Deserialize<'de>>(&self, bytes: &'de [u8]) -> Result<T, Error> {
deserialize_value(|driver| self.drive_slice(bytes, driver))
}
fn drive_slice<'de>(
&self,
bytes: &'de [u8],
driver: &mut DeserializeDriver<'_, 'de>,
) -> Result<(), Error> {
drive_single(
Deserializer::from_slice_with_config(bytes, self.clone()),
driver,
)
}
}
#[derive(Debug, Clone)]
#[must_use]
pub struct DeserializerConfigBuilder {
value: DeserializerConfig,
}
impl DeserializerConfigBuilder {
pub const fn new() -> DeserializerConfigBuilder {
DeserializerConfigBuilder {
value: DeserializerConfig::new(),
}
}
pub const fn version(mut self, version: Version) -> DeserializerConfigBuilder {
self.value.set_version(version);
self
}
pub const fn alias_limit(mut self, limit: usize) -> DeserializerConfigBuilder {
self.value.set_alias_limit(limit);
self
}
pub const fn merge_keys(mut self, yes: bool) -> DeserializerConfigBuilder {
self.value.set_merge_keys(yes);
self
}
pub fn context(mut self, context: deser_core::Context) -> DeserializerConfigBuilder {
self.value.set_context(context);
self
}
pub const fn build(self) -> DeserializerConfig {
let value = unsafe { core::ptr::read(&self.value) };
core::mem::forget(self);
value
}
}
impl Default for DeserializerConfigBuilder {
fn default() -> DeserializerConfigBuilder {
DeserializerConfigBuilder::new()
}
}
pub struct Deserializer<'a> {
input: &'a str,
parser: Parser<'a>,
peeked: Option<YamlEvent<'a>>,
started: bool,
pending_error: Option<Error>,
failed: bool,
config: DeserializerConfig,
track_merges: bool,
source: Option<Arc<str>>,
doc: Document<'a>,
}
#[derive(Clone)]
enum Node<'a> {
Scalar {
tag: Option<Cow<'a, str>>,
style: ScalarStyle,
value: Cow<'a, str>,
start: Mark,
end: usize,
},
Start {
tag: Option<Cow<'a, str>>,
is_map: bool,
flow: bool,
start: Mark,
end: usize,
},
End {
is_map: bool,
start: Mark,
end: usize,
},
Alias { range: (usize, usize) },
}
#[derive(Default)]
struct Document<'a> {
version: Version,
nodes: Vec<Node<'a>>,
anchors: HashMap<Cow<'a, str>, (usize, usize)>,
open: Vec<OpenNode<'a>>,
captured: Option<(usize, usize)>,
depth: usize,
}
struct OpenNode<'a> {
anchor: Option<Cow<'a, str>>,
start: usize,
depth: usize,
capture: bool,
}
impl<'a> Document<'a> {
fn reset(&mut self, version: Version) {
self.version = version;
self.nodes.clear();
self.anchors.clear();
self.open.clear();
self.captured = None;
self.depth = 0;
}
fn record(&mut self, event: YamlEvent<'a>, capture: bool) -> Result<Node<'a>, Error> {
let start = event.start;
let end = event.end.offset;
let is_map = matches!(event.kind, EventKind::MappingStart { .. });
let (node, anchor) = match event.kind {
EventKind::Scalar {
props,
style,
value,
} => (
Node::Scalar {
tag: props.tag,
style,
value,
start,
end,
},
props.anchor,
),
EventKind::SequenceStart { props, flow } | EventKind::MappingStart { props, flow } => {
self.depth += 1;
(
Node::Start {
tag: props.tag,
is_map,
flow,
start,
end,
},
props.anchor,
)
}
EventKind::SequenceEnd | EventKind::MappingEnd => {
let is_map = event.kind == EventKind::MappingEnd;
self.depth -= 1;
let node = Node::End { is_map, start, end };
if !self.open.is_empty() {
self.nodes.push(node.clone());
let depth = self.depth + 1;
if let Some(open) = self.open.pop_if(|x| x.depth == depth) {
let range = (open.start, self.nodes.len());
if let Some(name) = open.anchor {
self.anchors.insert(name, range);
}
if open.capture {
self.captured = Some(range);
}
}
}
return Ok(node);
}
EventKind::Alias { anchor } => {
if self.open.iter().any(|x| x.anchor.as_ref() == Some(&anchor)) {
return Err(error_at(start, "recursive alias"));
}
let range = match self.anchors.get(&anchor) {
Some(&range) => range,
None => return Err(error_at(start, &format!("unknown anchor `{}`", anchor))),
};
let node = Node::Alias { range };
if !self.open.is_empty() {
self.nodes.push(node.clone());
}
return Ok(node);
}
_ => unreachable!("unexpected event in document"),
};
let is_start = matches!(node, Node::Start { .. });
if anchor.is_some() || (capture && is_start) || !self.open.is_empty() {
let index = self.nodes.len();
self.nodes.push(node.clone());
if is_start && (anchor.is_some() || capture) {
self.open.push(OpenNode {
anchor,
start: index,
depth: self.depth,
capture,
});
} else if let Some(name) = anchor {
self.anchors.insert(name, (index, index + 1));
}
}
Ok(node)
}
fn node_end(&self, index: usize) -> usize {
if !matches!(self.nodes[index], Node::Start { .. }) {
return index + 1;
}
let mut depth = 0;
for (offset, node) in self.nodes[index..].iter().enumerate() {
match node {
Node::Start { .. } => depth += 1,
Node::End { .. } => {
depth -= 1;
if depth == 0 {
return index + offset + 1;
}
}
_ => {}
}
}
unreachable!("unbalanced recording");
}
fn resolve_range(&self, mut range: (usize, usize)) -> (usize, usize) {
while let Node::Alias { range: target } = self.nodes[range.0] {
range = target;
}
range
}
fn items(&self, range: (usize, usize)) -> impl Iterator<Item = (usize, usize)> + '_ {
let mut index = range.0 + 1;
std::iter::from_fn(move || {
if index + 1 >= range.1 {
return None;
}
let item = (index, self.node_end(index));
index = item.1;
Some(item)
})
}
}
#[derive(PartialEq, Eq, Hash)]
enum KeyId<'a> {
Null,
Bool(bool),
Int(bool, u128),
Float(u64),
Str(Cow<'a, str>),
Bytes(Vec<u8>),
Tagged(Cow<'a, str>, Cow<'a, str>),
}
impl<'a> KeyId<'a> {
fn of_scalar(
tag: &Option<Cow<'a, str>>,
style: ScalarStyle,
value: &Cow<'a, str>,
version: Version,
) -> Option<KeyId<'a>> {
let atom = match tag {
None if style == ScalarStyle::Plain => resolve_plain(value.clone(), version),
None => return Some(KeyId::Str(value.clone())),
Some(tag) => match classify_tag(tag) {
ScalarTag::Str => return Some(KeyId::Str(value.clone())),
ScalarTag::Standard(name) => resolve_standard(name, value.clone(), version).ok()?,
ScalarTag::Custom => return Some(KeyId::Tagged(tag.clone(), value.clone())),
},
};
Some(match atom {
Atom::Null => KeyId::Null,
Atom::Bool(value) => KeyId::Bool(value),
Atom::U64(value) => KeyId::Int(false, value.into()),
Atom::I64(value) => KeyId::Int(value < 0, value.unsigned_abs().into()),
Atom::F64(value) => KeyId::Float(value.to_bits()),
Atom::Str(value) => KeyId::Str(value.into_cow()),
Atom::Bytes(value) => KeyId::Bytes(value.into_owned()),
Atom::Ext(ref ext) => {
if let Some(&value) = ext.downcast_ref::<u128>() {
KeyId::Int(false, value)
} else if let Some(&value) = ext.downcast_ref::<i128>() {
KeyId::Int(value < 0, value.unsigned_abs())
} else {
return None;
}
}
_ => return None,
})
}
}
fn is_merge_key(tag: &Option<Cow<'_, str>>, style: ScalarStyle, value: &str) -> bool {
tag.is_none() && style == ScalarStyle::Plain && value == "<<"
}
enum Pending<'a> {
Range(usize, usize),
Node(Node<'a>),
}
struct Frame<'a> {
is_map: bool,
expect_key: bool,
keys: HashSet<KeyId<'a>>,
sources: Vec<(usize, usize)>,
}
impl<'a> Deserializer<'a> {
#[allow(clippy::should_implement_trait)]
pub fn from_str(input: &'a str) -> Deserializer<'a> {
Deserializer::from_str_with_config(input, DeserializerConfig::new())
}
pub fn from_str_with_config(input: &'a str, config: DeserializerConfig) -> Deserializer<'a> {
let track_merges = config.merge_keys && input.contains("<<");
Deserializer {
input,
parser: Parser::new(input),
peeked: None,
started: false,
pending_error: None,
failed: false,
config,
track_merges,
source: None,
doc: Document::default(),
}
}
pub fn from_slice(input: &'a [u8]) -> Deserializer<'a> {
Deserializer::from_slice_with_config(input, DeserializerConfig::new())
}
pub fn from_slice_with_config(input: &'a [u8], config: DeserializerConfig) -> Deserializer<'a> {
match str_from_utf8(input) {
Ok(input) => Deserializer::from_str_with_config(input, config),
Err(err) => {
let mut rv = Deserializer::from_str_with_config("", config);
rv.pending_error = Some(err);
rv.failed = true;
rv
}
}
}
pub fn config(&self) -> &DeserializerConfig {
&self.config
}
pub fn is_end(&mut self) -> bool {
if self.failed {
return self.pending_error.is_none();
}
match self.peek_event() {
Ok(event) => event.kind == EventKind::StreamEnd,
Err(err) => {
self.pending_error = Some(err);
false
}
}
}
pub fn end(&mut self) -> Result<(), Error> {
if self.is_end() {
Ok(())
} else if let Some(err) = self.pending_error.take() {
Err(err)
} else {
Err(Error::new(
ErrorKind::Syntax,
"expected a single document, found more",
))
}
}
pub fn deserialize<T: Deserialize<'a>>(&mut self) -> Result<T, Error> {
de::Deserializer::deserialize(self)
}
pub fn deserialize_with<T, F>(&mut self, setup: F) -> Result<T, Error>
where
T: Deserialize<'a>,
F: FnOnce(&mut DeserializeDriver<'_, 'a>),
{
de::Deserializer::deserialize_with(self, setup)
}
pub fn iter<T: Deserialize<'a>>(&mut self) -> Iter<'_, 'a, T> {
Iter {
de: self,
failed: false,
_marker: PhantomData,
}
}
pub fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
if !self.config.context.is_empty() {
driver.set_default_context(self.config.context.clone());
}
if let Some(err) = self.pending_error.take() {
return Err(err);
}
if self.failed {
return Err(Error::new(
ErrorKind::InvalidState,
"cannot continue after a syntax error",
));
}
let event = self.next_event()?;
let version = match event.kind {
EventKind::DocumentStart { version, .. } => match version {
Some((1, minor)) if minor < 2 => Version::V1_1,
Some(_) => Version::V1_2,
None => self.config.version,
},
EventKind::StreamEnd => {
self.peeked = Some(event);
return Err(Error::new(ErrorKind::EndOfFile, "no more documents"));
}
_ => unreachable!("expected document start"),
};
self.doc.reset(version);
if TrackLocations::of(driver.state()) {
let source = self.source.get_or_insert_with(|| self.input.into());
Source(source.clone()).set(driver.state_mut());
}
let input = self.input;
let rv = self.drive_document(driver).map_err(|mut err| {
err.resolve_position(input.as_bytes());
err
});
if rv.is_err() && !self.failed {
if let Err(err) = self.skip_document() {
self.pending_error = Some(err);
}
}
rv
}
fn ensure_started(&mut self) -> Result<(), Error> {
if !self.started {
self.started = true;
let event = self.parser_event()?;
debug_assert_eq!(event.kind, EventKind::StreamStart);
}
Ok(())
}
fn parser_event(&mut self) -> Result<YamlEvent<'a>, Error> {
self.parser.next_event().inspect_err(|_| {
self.failed = true;
})
}
fn next_event(&mut self) -> Result<YamlEvent<'a>, Error> {
self.ensure_started()?;
match self.peeked.take() {
Some(event) => Ok(event),
None => self.parser_event(),
}
}
fn peek_event(&mut self) -> Result<&YamlEvent<'a>, Error> {
if self.peeked.is_none() {
let event = self.next_event()?;
self.peeked = Some(event);
}
Ok(self.peeked.as_ref().unwrap())
}
fn skip_document(&mut self) -> Result<(), Error> {
loop {
if let EventKind::DocumentEnd { .. } = self.next_event()?.kind {
return Ok(());
}
}
}
fn drive_document(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
let mut pending: Vec<Pending<'a>> = Vec::new();
let mut replayed = 0;
let track_merges = self.track_merges;
let mut frames: Vec<Frame<'a>> = Vec::new();
let mut merge_value_follows = false;
loop {
let (node, index) =
match self.next_node(&mut pending, &mut replayed, merge_value_follows)? {
Some(rv) => rv,
None => return Ok(()),
};
if merge_value_follows {
merge_value_follows = false;
let range = self.merge_source(node, index, &mut pending)?;
let frame = frames.last_mut().unwrap();
frame.sources.push(range);
frame.expect_key = true;
continue;
}
if track_merges
&& let Some(frame) = frames.last_mut()
&& frame.is_map
{
if frame.expect_key
&& let Node::Scalar {
ref tag,
style,
ref value,
..
} = node
{
if is_merge_key(tag, style, value) {
frame.expect_key = false;
merge_value_follows = true;
continue;
}
if let Some(id) = KeyId::of_scalar(tag, style, value, self.doc.version) {
frame.keys.insert(id);
}
}
if !matches!(node, Node::Alias { .. } | Node::End { .. }) {
frame.expect_key = !frame.expect_key;
}
}
match node {
Node::Scalar {
tag,
style,
value,
start,
end,
} => {
let version = self.doc.version;
emit_scalar(driver, tag, style, value, version, start, end)?;
}
Node::Start {
tag,
is_map,
flow,
start,
end,
} => {
if flow {
Layout::Compact.set(driver.state_mut());
}
if track_merges {
frames.push(Frame {
is_map,
expect_key: true,
keys: HashSet::new(),
sources: Vec::new(),
});
}
let event = if is_map {
Event::map_start()
} else {
Event::seq_start()
};
driver.state_mut().set_input_range(start.offset, end);
match tag {
Some(tag) => match is_collection_tag(&tag, is_map) {
Ok(true) => driver.emit(event)?,
Ok(false) => emit_tagged(driver, &tag, event)?,
Err(msg) => return Err(error_at(start, msg)),
},
None => driver.emit(event)?,
}
}
Node::End { is_map, start, end } => {
if track_merges {
let frame = frames.last_mut().unwrap();
if !frame.sources.is_empty() {
let sources = std::mem::take(&mut frame.sources);
let entries =
self.merged_entries(&sources, &mut frame.keys, &mut replayed)?;
pending.push(Pending::Node(Node::End { is_map, start, end }));
for (key, value) in entries.into_iter().rev() {
pending.push(Pending::Range(value.0, value.1));
pending.push(Pending::Range(key.0, key.1));
}
continue;
}
frames.pop();
}
let event = if is_map { Event::MapEnd } else { Event::SeqEnd };
driver.state_mut().set_input_range(start.offset, end);
driver.emit(event)?;
}
Node::Alias { range } => pending.push(Pending::Range(range.0, range.1)),
}
}
}
fn next_node(
&mut self,
pending: &mut Vec<Pending<'a>>,
replayed: &mut usize,
capture: bool,
) -> Result<Option<(Node<'a>, Option<usize>)>, Error> {
loop {
let (node, index) = match pending.last_mut() {
Some(Pending::Range(start, end)) => {
if start == end {
pending.pop();
continue;
}
let index = *start;
*start += 1;
(self.doc.nodes[index].clone(), Some(index))
}
Some(Pending::Node(_)) => match pending.pop() {
Some(Pending::Node(node)) => return Ok(Some((node, None))),
_ => unreachable!(),
},
None => {
let event = self.next_event()?;
if let EventKind::DocumentEnd { .. } = event.kind {
return Ok(None);
}
return Ok(Some((self.doc.record(event, capture)?, None)));
}
};
self.count_replayed(replayed, 1)?;
return Ok(Some((node, index)));
}
}
fn count_replayed(&self, replayed: &mut usize, count: usize) -> Result<(), Error> {
*replayed += count;
if *replayed > self.config.alias_limit {
Err(Error::new(
ErrorKind::LimitExceeded,
"aliases expand to too many events",
))
} else {
Ok(())
}
}
fn merge_source(
&mut self,
node: Node<'a>,
index: Option<usize>,
pending: &mut [Pending<'a>],
) -> Result<(usize, usize), Error> {
match node {
Node::Alias { range } => Ok(range),
Node::Start { .. } => match index {
Some(index) => {
let end = self.doc.node_end(index);
if let Some(Pending::Range(start, _)) = pending.last_mut() {
*start = end;
}
Ok((index, end))
}
None => {
while self.doc.captured.is_none() {
let event = self.next_event()?;
self.doc.record(event, false)?;
}
Ok(self.doc.captured.take().unwrap())
}
},
Node::Scalar { start, .. } | Node::End { start, .. } => Err(error_at(
start,
"the value of a merge key must be a mapping or a sequence of mappings",
)),
}
}
#[allow(clippy::type_complexity)]
fn merged_entries(
&self,
sources: &[(usize, usize)],
keys: &mut HashSet<KeyId<'a>>,
replayed: &mut usize,
) -> Result<Vec<((usize, usize), (usize, usize))>, Error> {
let mut entries = Vec::new();
let mut stack = Vec::new();
self.push_merge_sources(sources, &mut stack);
while let Some(range) = stack.pop() {
match self.doc.nodes[range.0] {
Node::Start { is_map: true, .. } => {}
Node::Start { start, .. } | Node::Scalar { start, .. } => {
return Err(error_at(
start,
"merge keys can only merge mappings or sequences of mappings",
));
}
_ => unreachable!(),
}
self.count_replayed(replayed, range.1 - range.0)?;
let mut nested = Vec::new();
let mut items = self.doc.items(range);
while let (Some(key), Some(value)) = (items.next(), items.next()) {
if let Node::Scalar {
tag: ref key_tag,
style,
value: ref key_value,
..
} = self.doc.nodes[self.doc.resolve_range(key).0]
{
if is_merge_key(key_tag, style, key_value) {
nested.push(value);
continue;
}
let version = self.doc.version;
if let Some(id) = KeyId::of_scalar(key_tag, style, key_value, version)
&& !keys.insert(id)
{
continue;
}
}
entries.push((key, value));
}
self.push_merge_sources(&nested, &mut stack);
}
Ok(entries)
}
fn push_merge_sources(&self, sources: &[(usize, usize)], stack: &mut Vec<(usize, usize)>) {
for &source in sources.iter().rev() {
let source = self.doc.resolve_range(source);
match self.doc.nodes[source.0] {
Node::Start { is_map: false, .. } => {
let items: Vec<_> = self
.doc
.items(source)
.map(|item| self.doc.resolve_range(item))
.collect();
stack.extend(items.into_iter().rev());
}
_ => stack.push(source),
}
}
}
}
#[inline]
fn emit_scalar<'a>(
driver: &mut DeserializeDriver<'_, 'a>,
tag: Option<Cow<'_, str>>,
style: ScalarStyle,
value: Cow<'a, str>,
version: Version,
start: Mark,
end: usize,
) -> Result<(), Error> {
driver.state_mut().set_input_range(start.offset, end);
let tag = match tag {
None if style == ScalarStyle::Plain => {
return driver.emit_borrowed(resolve_plain_implicit(value, version));
}
None => return driver.emit_borrowed(Atom::Str(value.into())),
Some(tag) => tag,
};
match classify_tag(&tag) {
ScalarTag::Str => driver.emit_borrowed(Atom::Str(value.into())),
ScalarTag::Standard(name) => match resolve_standard(name, value, version) {
Ok(atom) => driver.emit_borrowed(atom),
Err(msg) => Err(error_at(start, msg)),
},
ScalarTag::Custom => emit_tagged(driver, &tag, Atom::Str(value.into())),
}
}
#[cold]
fn emit_tagged<'a, E: Into<Event<'a>>>(
driver: &mut DeserializeDriver<'_, 'a>,
tag: &str,
event: E,
) -> Result<(), Error> {
driver.state_mut().event_mut::<NodeTag>().0 = Some(tag.to_string());
driver.emit_borrowed(event)
}
fn str_from_utf8(bytes: &[u8]) -> Result<&str, Error> {
#[cfg(feature = "speedups")]
{
if simdutf8::basic::from_utf8(bytes).is_ok() {
return Ok(unsafe { std::str::from_utf8_unchecked(bytes) });
}
}
std::str::from_utf8(bytes)
.map_err(|err| Error::with_offset(ErrorKind::Syntax, "invalid UTF-8", err.valid_up_to()))
}
pub struct Iter<'b, 'a, T> {
de: &'b mut Deserializer<'a>,
failed: bool,
_marker: PhantomData<fn() -> T>,
}
impl<'b, 'a, T: Deserialize<'a>> Iterator for Iter<'b, 'a, T> {
type Item = Result<T, Error>;
fn next(&mut self) -> Option<Self::Item> {
if self.failed || self.de.is_end() {
return None;
}
let rv = self.de.deserialize();
self.failed = rv.is_err();
Some(rv)
}
}
impl<'a> de::Deserializer<'a> for Deserializer<'a> {
fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
Deserializer::drive(self, driver)
}
}
pub fn from_str<'de, T: Deserialize<'de>>(s: &'de str) -> Result<T, Error> {
DeserializerConfig::new().from_str(s)
}
pub fn from_slice<'de, T: Deserialize<'de>>(bytes: &'de [u8]) -> Result<T, Error> {
DeserializerConfig::new().from_slice(bytes)
}
fn drive_single<'de>(
mut deserializer: Deserializer<'de>,
driver: &mut DeserializeDriver<'_, 'de>,
) -> Result<(), Error> {
if deserializer.is_end() {
return de::Deserializer::drive(&mut EmptyDocument, driver);
}
de::Deserializer::drive(&mut deserializer, driver)?;
deserializer.end()
}
struct EmptyDocument;
impl<'de> de::Deserializer<'de> for EmptyDocument {
fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'de>) -> Result<(), Error> {
driver.emit(Atom::Implicit(Implicit::new("", ImplicitValue::Null)))
}
}