use std::collections::VecDeque;
use std::marker::PhantomData;
use std::sync::Arc;
use facet_core::{Facet, Shape};
use facet_reflect::{HeapValue, Partial, Span};
use facet_solver::{FieldInfo, KeyResult, SatisfyResult, Schema, Solver};
use crate::{FormatParser, ParseEvent, type_plan_cache::cached_type_plan_arc};
mod error;
pub use entry::MetaSource;
pub use error::*;
mod setters;
mod entry;
mod dynamic;
mod eenum;
mod pointer;
mod scalar_matches;
mod struct_simple;
mod struct_with_flatten;
mod path_navigator;
pub const DEFAULT_EVENT_BUFFER_SIZE: usize = 512;
struct DeserializerSavePoint<'input> {
parser_save_point: crate::SavePoint,
event_buffer: VecDeque<ParseEvent<'input>>,
}
pub struct FormatDeserializer<'parser, 'input, const BORROW: bool> {
parser: &'parser mut dyn FormatParser<'input>,
last_span: Span,
event_buffer: VecDeque<ParseEvent<'input>>,
buffer_capacity: usize,
is_non_self_describing: bool,
_marker: PhantomData<&'input ()>,
}
impl<'parser, 'input> FormatDeserializer<'parser, 'input, true> {
pub fn new(parser: &'parser mut dyn FormatParser<'input>) -> Self {
Self::with_buffer_capacity(parser, DEFAULT_EVENT_BUFFER_SIZE)
}
pub fn with_buffer_capacity(
parser: &'parser mut dyn FormatParser<'input>,
buffer_capacity: usize,
) -> Self {
let is_non_self_describing = !parser.is_self_describing();
Self {
parser,
last_span: Span { offset: 0, len: 0 },
event_buffer: VecDeque::with_capacity(buffer_capacity),
buffer_capacity,
is_non_self_describing,
_marker: PhantomData,
}
}
}
impl<'parser, 'input> FormatDeserializer<'parser, 'input, false> {
pub fn new_owned(parser: &'parser mut dyn FormatParser<'input>) -> Self {
Self::with_buffer_capacity_owned(parser, DEFAULT_EVENT_BUFFER_SIZE)
}
pub fn with_buffer_capacity_owned(
parser: &'parser mut dyn FormatParser<'input>,
buffer_capacity: usize,
) -> Self {
let is_non_self_describing = !parser.is_self_describing();
Self {
parser,
last_span: Span { offset: 0, len: 0 },
event_buffer: VecDeque::with_capacity(buffer_capacity),
buffer_capacity,
is_non_self_describing,
_marker: PhantomData,
}
}
}
impl<'parser, 'input, const BORROW: bool> FormatDeserializer<'parser, 'input, BORROW> {
pub fn parser_mut(&mut self) -> &mut dyn FormatParser<'input> {
self.parser
}
fn save(&mut self) -> DeserializerSavePoint<'input> {
DeserializerSavePoint {
parser_save_point: self.parser.save(),
event_buffer: self.event_buffer.clone(),
}
}
fn restore(&mut self, save_point: DeserializerSavePoint<'input>) {
self.parser.restore(save_point.parser_save_point);
self.event_buffer = save_point.event_buffer;
}
}
impl<'parser, 'input> FormatDeserializer<'parser, 'input, true> {
pub fn deserialize<T>(&mut self) -> Result<T, DeserializeError>
where
T: Facet<'input>,
{
let wip = Partial::alloc_with_plan(cached_type_plan_arc::<T>()?)?;
let partial = self.deserialize_into(wip, MetaSource::FromEvents)?;
let _guard = SpanGuard::new(self.last_span);
let heap_value = partial.build()?;
Ok(heap_value.materialize::<T>()?)
}
pub fn deserialize_root<T>(&mut self) -> Result<T, DeserializeError>
where
T: Facet<'input>,
{
self.deserialize()
}
pub fn deserialize_deferred<T>(&mut self) -> Result<T, DeserializeError>
where
T: Facet<'input>,
{
let wip = Partial::alloc_with_plan(cached_type_plan_arc::<T>()?)?;
let wip = wip.begin_deferred()?;
let partial = self.deserialize_into(wip, MetaSource::FromEvents)?;
let _guard = SpanGuard::new(self.last_span);
let partial = partial.finish_deferred()?;
let heap_value = partial.build()?;
Ok(heap_value.materialize::<T>()?)
}
}
impl<'parser, 'input> FormatDeserializer<'parser, 'input, false> {
pub fn deserialize<T>(&mut self) -> Result<T, DeserializeError>
where
T: Facet<'static>,
{
let wip = Partial::alloc_owned_with_plan(cached_type_plan_arc::<T>()?)?;
#[allow(unsafe_code)]
let wip: Partial<'input, false> = unsafe { core::mem::transmute(wip) };
let partial = self.deserialize_into(wip, MetaSource::FromEvents)?;
let _guard = SpanGuard::new(self.last_span);
let heap_value = partial.build()?;
#[allow(unsafe_code)]
let heap_value: HeapValue<'static, false> = unsafe { core::mem::transmute(heap_value) };
Ok(heap_value.materialize::<T>()?)
}
pub fn deserialize_root<T>(&mut self) -> Result<T, DeserializeError>
where
T: Facet<'static>,
{
self.deserialize()
}
pub fn deserialize_deferred<T>(&mut self) -> Result<T, DeserializeError>
where
T: Facet<'static>,
{
let wip = Partial::alloc_owned_with_plan(cached_type_plan_arc::<T>()?)?;
#[allow(unsafe_code)]
let wip: Partial<'input, false> = unsafe { core::mem::transmute(wip) };
let wip = wip.begin_deferred()?;
let partial = self.deserialize_into(wip, MetaSource::FromEvents)?;
let _guard = SpanGuard::new(self.last_span);
let partial = partial.finish_deferred()?;
let heap_value = partial.build()?;
#[allow(unsafe_code)]
let heap_value: HeapValue<'static, false> = unsafe { core::mem::transmute(heap_value) };
Ok(heap_value.materialize::<T>()?)
}
pub fn deserialize_with_shape<T>(
&mut self,
source_shape: &'static Shape,
) -> Result<T, DeserializeError>
where
T: Facet<'static>,
{
let wip = Partial::alloc_owned_with_plan(cached_type_plan_arc::<T>()?)?;
#[allow(unsafe_code)]
let wip: Partial<'input, false> = unsafe { core::mem::transmute(wip) };
let partial = self.deserialize_into_with_shape(wip, source_shape)?;
let _guard = SpanGuard::new(self.last_span);
let heap_value = partial.build()?;
#[allow(unsafe_code)]
let heap_value: HeapValue<'static, false> = unsafe { core::mem::transmute(heap_value) };
Ok(heap_value.materialize::<T>()?)
}
}
impl<'parser, 'input, const BORROW: bool> FormatDeserializer<'parser, 'input, BORROW> {
#[inline]
fn refill_buffer(&mut self) -> Result<(), ParseError> {
let _old_len = self.event_buffer.len();
self.parser
.next_events(&mut self.event_buffer, self.buffer_capacity)?;
let _new_len = self.event_buffer.len();
trace!("buffer refill {_old_len} => {_new_len} events");
Ok(())
}
#[inline(always)]
fn is_non_self_describing(&self) -> bool {
self.is_non_self_describing
}
#[inline]
fn expect_event(
&mut self,
expected: &'static str,
) -> Result<ParseEvent<'input>, DeserializeError> {
if self.is_non_self_describing() {
let event = self.parser.next_event()?.ok_or_else(|| {
DeserializeErrorKind::UnexpectedEof { expected }.with_span(self.last_span)
})?;
trace!(?event, expected, "expect_event (direct): got event");
self.last_span = event.span;
return Ok(event);
}
if self.event_buffer.is_empty() {
self.refill_buffer()?;
}
let event = self.event_buffer.pop_front().ok_or_else(|| {
DeserializeErrorKind::UnexpectedEof { expected }.with_span(self.last_span)
})?;
trace!(?event, expected, "expect_event: got event");
self.last_span = event.span;
Ok(event)
}
#[inline]
fn expect_peek(
&mut self,
expected: &'static str,
) -> Result<ParseEvent<'input>, DeserializeError> {
self.peek_event_opt()?.ok_or_else(|| {
DeserializeErrorKind::UnexpectedEof { expected }.with_span(self.last_span)
})
}
#[inline]
fn peek_event_opt(&mut self) -> Result<Option<ParseEvent<'input>>, DeserializeError> {
if self.is_non_self_describing() {
let event = self.parser.peek_event()?;
if let Some(ref _e) = event {
trace!(?_e, "peek_event_opt (direct): peeked event");
}
return Ok(event);
}
if self.event_buffer.is_empty() {
self.refill_buffer()?;
}
let event = self.event_buffer.front().cloned();
if let Some(ref _e) = event {
trace!(?_e, "peeked event");
}
Ok(event)
}
#[inline]
pub(crate) fn count_buffered_sequence_items(&self) -> usize {
use crate::ParseEventKind;
let mut count = 0usize;
let mut depth = 0i32;
for event in &self.event_buffer {
match &event.kind {
ParseEventKind::StructStart(_) | ParseEventKind::SequenceStart(_) => {
if depth == 0 {
count += 1;
}
depth += 1;
}
ParseEventKind::StructEnd | ParseEventKind::SequenceEnd => {
depth -= 1;
if depth < 0 {
return count;
}
}
ParseEventKind::Scalar(_) if depth == 0 => {
count += 1;
}
_ => {}
}
}
count
}
#[inline]
fn skip_value_with_span(&mut self) -> Result<(usize, usize), DeserializeError> {
use crate::ParseEventKind;
let first_event = self.expect_peek("value to skip")?;
let start_offset = first_event.span.offset as usize;
#[allow(unused_assignments)]
let mut end_offset = 0usize;
let mut depth = 0i32;
loop {
let event = self.expect_event("value to skip")?;
end_offset = event.span.end();
match &event.kind {
ParseEventKind::StructStart(_) | ParseEventKind::SequenceStart(_) => {
depth += 1;
}
ParseEventKind::StructEnd | ParseEventKind::SequenceEnd => {
depth -= 1;
if depth <= 0 {
return Ok((start_offset, end_offset));
}
}
ParseEventKind::Scalar(_) if depth == 0 => {
return Ok((start_offset, end_offset));
}
_ => {}
}
}
}
#[inline]
fn skip_value(&mut self) -> Result<(), DeserializeError> {
self.skip_value_with_span()?;
Ok(())
}
#[inline]
fn capture_raw(&mut self) -> Result<Option<&'input str>, DeserializeError> {
let Some(input) = self.parser.input() else {
self.skip_value()?;
return Ok(None);
};
let (start, end) = self.skip_value_with_span()?;
if end <= input.len() {
let raw = core::str::from_utf8(&input[start..end]).map_err(|_| {
DeserializeErrorKind::InvalidValue {
message: "raw capture contains invalid UTF-8".into(),
}
.with_span(self.last_span)
})?;
Ok(Some(raw))
} else {
Ok(None)
}
}
#[inline]
fn next_event_opt(&mut self) -> Result<Option<ParseEvent<'input>>, DeserializeError> {
if self.event_buffer.is_empty() {
self.refill_buffer()?;
}
let Some(event) = self.event_buffer.pop_front() else {
return Ok(None);
};
self.last_span = event.span;
Ok(Some(event))
}
pub(crate) fn solve_variant(
&mut self,
shape: &'static facet_core::Shape,
) -> Result<Option<crate::SolveOutcome>, crate::SolveVariantError> {
let schema = Arc::new(Schema::build_auto(shape)?);
let mut solver = Solver::new(&schema);
let save_point = self.save();
let mut depth = 0i32;
let mut in_struct = false;
let mut expecting_value = false;
let mut pending_ambiguous: Option<(String, Vec<(&FieldInfo, u64)>)> = None;
let result = loop {
let event = self.next_event_opt().map_err(|e| {
crate::SolveVariantError::Parser(ParseError::new(
e.span.unwrap_or(self.last_span),
e.kind,
))
})?;
let Some(event) = event else {
self.restore(save_point);
return Ok(None);
};
if expecting_value && depth == 1 && in_struct {
expecting_value = false;
if let Some((key, fields)) = pending_ambiguous.take()
&& let crate::ParseEventKind::Scalar(scalar) = &event.kind
{
let satisfied_shapes = select_best_ambiguous_scalar_shapes(scalar, &fields);
match solver.satisfy_at_path(&[key.as_str()], &satisfied_shapes) {
SatisfyResult::Solved(handle) => break Some(handle),
SatisfyResult::NoMatch => break None,
SatisfyResult::Continue => {}
}
}
}
match event.kind {
crate::ParseEventKind::StructStart(_) => {
depth += 1;
if depth == 1 {
in_struct = true;
}
}
crate::ParseEventKind::StructEnd => {
depth -= 1;
if depth == 0 {
break None;
}
}
crate::ParseEventKind::SequenceStart(_) => {
depth += 1;
}
crate::ParseEventKind::SequenceEnd => {
depth -= 1;
}
crate::ParseEventKind::FieldKey(ref key) => {
if depth == 1 && in_struct {
if let Some(name) = key.name() {
match solver.see_key(name.clone()) {
KeyResult::Solved(handle) => {
break Some(handle);
}
KeyResult::Ambiguous { fields } => {
pending_ambiguous = Some((name.to_string(), fields));
}
KeyResult::Unknown | KeyResult::Unambiguous { .. } => {
pending_ambiguous = None;
}
}
}
expecting_value = true;
}
}
crate::ParseEventKind::Scalar(_)
| crate::ParseEventKind::OrderedField
| crate::ParseEventKind::VariantTag(_) => {
if expecting_value {
expecting_value = false;
}
}
}
};
self.restore(save_point);
match result {
Some(handle) => {
let idx = handle.index();
Ok(Some(crate::SolveOutcome {
schema,
resolution_index: idx,
}))
}
None => Ok(None),
}
}
fn mk_err(
&self,
wip: &Partial<'input, BORROW>,
kind: DeserializeErrorKind,
) -> DeserializeError {
DeserializeError {
span: Some(self.last_span),
path: Some(wip.path()),
kind,
}
}
}
fn select_best_ambiguous_scalar_shapes(
scalar: &crate::ScalarValue<'_>,
fields: &[(&FieldInfo, u64)],
) -> Vec<&'static Shape> {
let mut matches: Vec<(&'static Shape, u8, u64)> = Vec::new();
let mut best_quality: Option<u8> = None;
for (field, score) in fields {
let Some(quality) =
crate::deserializer::scalar_matches::scalar_match_quality(scalar, field.value_shape)
else {
continue;
};
match best_quality {
Some(best) if quality > best => continue,
Some(best) if quality < best => {
matches.clear();
best_quality = Some(quality);
}
None => {
best_quality = Some(quality);
}
_ => {}
}
if !matches.iter().any(|(shape, _, existing_score)| {
core::ptr::eq(*shape, field.value_shape) && *existing_score == *score
}) {
matches.push((field.value_shape, quality, *score));
}
}
let Some(best_quality) = best_quality else {
return Vec::new();
};
let best_specificity = matches
.iter()
.filter(|(_, quality, _)| *quality == best_quality)
.map(|(_, _, score)| *score)
.min()
.unwrap_or(u64::MAX);
matches
.into_iter()
.filter(|(_, quality, score)| *quality == best_quality && *score == best_specificity)
.map(|(shape, _, _)| shape)
.collect()
}