use core::future::Future;
use core::mem;
use core::pin::Pin;
use core::task::{Context, Poll};
use crate::map_arm::{
ArmState, ConcatDispatchProj, ConcatDispatchState, ConcatRaceState, DetectDuplicatesOwned,
MapArmBase, MapArmSlot, NextKey, SlotDispatchProj, SlotDispatchState, SlotRaceState,
StackConcat, TagDispatchProj, TagDispatchState, TagInjectingStackOwned, TagRaceState,
VirtualArmSlot, WrapperDispatchProj, WrapperDispatchState, WrapperRaceState, poll_key_slot,
};
use crate::{Chunk, DeserializeError, Probe};
pub trait Deserialize<'de, Extra = ()>: Sized {
async fn deserialize<D: Deserializer<'de>>(
d: D,
extra: Extra,
) -> Result<Probe<(D::Claim, Self)>, D::Error>;
}
pub trait Deserializer<'de>: Sized {
type Error: DeserializeError;
type Claim: 'de;
type EntryClaim: 'de;
type Entry: Entry<'de, Claim = Self::EntryClaim, Error = Self::Error>;
async fn entry<const N: usize, F, Fut, R>(
self,
f: F,
) -> Result<Probe<(Self::Claim, R)>, Self::Error>
where
F: FnMut([Self::Entry; N]) -> Fut,
Fut: Future<Output = Result<Probe<(Self::EntryClaim, R)>, Self::Error>>;
}
pub trait Entry<'de>: Sized {
type Error: DeserializeError;
type Claim: 'de;
type StrChunks: StrAccess<Claim = Self::Claim, Error = Self::Error>;
type BytesChunks: BytesAccess<Claim = Self::Claim, Error = Self::Error>;
type Map: MapAccess<'de, MapClaim = Self::Claim, Error = Self::Error>;
type Seq: SeqAccess<'de, SeqClaim = Self::Claim, Error = Self::Error>;
async fn deserialize_bool(self) -> Result<Probe<(Self::Claim, bool)>, Self::Error>;
async fn deserialize_u8(self) -> Result<Probe<(Self::Claim, u8)>, Self::Error>;
async fn deserialize_u16(self) -> Result<Probe<(Self::Claim, u16)>, Self::Error>;
async fn deserialize_u32(self) -> Result<Probe<(Self::Claim, u32)>, Self::Error>;
async fn deserialize_u64(self) -> Result<Probe<(Self::Claim, u64)>, Self::Error>;
async fn deserialize_u128(self) -> Result<Probe<(Self::Claim, u128)>, Self::Error>;
async fn deserialize_i8(self) -> Result<Probe<(Self::Claim, i8)>, Self::Error>;
async fn deserialize_i16(self) -> Result<Probe<(Self::Claim, i16)>, Self::Error>;
async fn deserialize_i32(self) -> Result<Probe<(Self::Claim, i32)>, Self::Error>;
async fn deserialize_i64(self) -> Result<Probe<(Self::Claim, i64)>, Self::Error>;
async fn deserialize_i128(self) -> Result<Probe<(Self::Claim, i128)>, Self::Error>;
async fn deserialize_f32(self) -> Result<Probe<(Self::Claim, f32)>, Self::Error>;
async fn deserialize_f64(self) -> Result<Probe<(Self::Claim, f64)>, Self::Error>;
async fn deserialize_char(self) -> Result<Probe<(Self::Claim, char)>, Self::Error>;
async fn deserialize_str(self) -> Result<Probe<(Self::Claim, &'de str)>, Self::Error>;
async fn deserialize_str_chunks(self) -> Result<Probe<Self::StrChunks>, Self::Error>;
async fn deserialize_bytes(self) -> Result<Probe<(Self::Claim, &'de [u8])>, Self::Error>;
async fn deserialize_bytes_chunks(self) -> Result<Probe<Self::BytesChunks>, Self::Error>;
async fn deserialize_map(self) -> Result<Probe<Self::Map>, Self::Error>;
async fn deserialize_seq(self) -> Result<Probe<Self::Seq>, Self::Error>;
async fn deserialize_option<T: Deserialize<'de, Extra>, Extra>(
self,
extra: Extra,
) -> Result<Probe<(Self::Claim, Option<T>)>, Self::Error>;
async fn deserialize_null(self) -> Result<Probe<Self::Claim>, Self::Error>;
async fn deserialize_value<T: Deserialize<'de, Extra>, Extra>(
self,
extra: Extra,
) -> Result<Probe<(Self::Claim, T)>, Self::Error>;
fn fork(&mut self) -> Self;
async fn skip(self) -> Result<Self::Claim, Self::Error>;
}
pub trait StrAccess: Sized {
type Claim;
type Error: DeserializeError;
fn fork(&mut self) -> Self;
async fn next_str<R>(
self,
f: impl FnOnce(&str) -> R,
) -> Result<Chunk<(Self, R), Self::Claim>, Self::Error>;
}
pub trait BytesAccess: Sized {
type Claim;
type Error: DeserializeError;
fn fork(&mut self) -> Self;
async fn next_bytes<R>(
self,
f: impl FnOnce(&[u8]) -> R,
) -> Result<Chunk<(Self, R), Self::Claim>, Self::Error>;
}
pub trait MapKeyProbe<'de>: Sized {
type Error: DeserializeError;
type KeyClaim: MapKeyClaim<'de, Error = Self::Error>;
fn fork(&mut self) -> Self;
async fn deserialize_key<K: Deserialize<'de, Extra>, Extra>(
self,
extra: Extra,
) -> Result<Probe<(Self::KeyClaim, K)>, Self::Error>;
}
pub trait MapKeyClaim<'de>: Sized {
type Error: DeserializeError;
type MapClaim: 'de;
type ValueProbe: MapValueProbe<'de, MapClaim = Self::MapClaim, Error = Self::Error>;
async fn into_value_probe(self) -> Result<Self::ValueProbe, Self::Error>;
}
pub trait MapValueProbe<'de>: Sized {
type Error: DeserializeError;
type MapClaim: 'de;
type ValueClaim: MapValueClaim<'de, MapClaim = Self::MapClaim, Error = Self::Error>;
fn fork(&mut self) -> Self;
async fn deserialize_value<V: Deserialize<'de, Extra>, Extra>(
self,
extra: Extra,
) -> Result<Probe<(Self::ValueClaim, V)>, Self::Error>;
async fn skip(self) -> Result<Self::ValueClaim, Self::Error>;
}
pub trait MapValueClaim<'de>: Sized {
type Error: DeserializeError;
type KeyProbe: MapKeyProbe<'de, Error = Self::Error>;
type MapClaim: 'de;
async fn next_key(
self,
unsatisfied: usize,
open: usize,
) -> Result<NextKey<Self::KeyProbe, Self::MapClaim>, Self::Error>;
}
pub trait MapAccess<'de>: Sized {
type Error: DeserializeError;
type MapClaim: 'de;
type KeyProbe: MapKeyProbe<'de, Error = Self::Error>;
fn fork(&mut self) -> Self;
async fn iterate<S: MapArmStack<'de, Self::KeyProbe>>(
self,
arms: S,
) -> Result<Probe<(Self::MapClaim, S::Outputs)>, Self::Error>;
}
pub type KP<'de, D> =
<<<D as Deserializer<'de>>::Entry as Entry<'de>>::Map as MapAccess<'de>>::KeyProbe;
pub type VC<'de, KP> =
<<<KP as MapKeyProbe<'de>>::KeyClaim as MapKeyClaim<'de>>::ValueProbe as MapValueProbe<'de>>::ValueClaim;
pub type VP<'de, KP> = <<KP as MapKeyProbe<'de>>::KeyClaim as MapKeyClaim<'de>>::ValueProbe;
pub type VP2<'de, D> = <<KP<'de, D> as MapKeyProbe<'de>>::KeyClaim as MapKeyClaim<'de>>::ValueProbe;
pub trait MapArmStack<'de, KP: MapKeyProbe<'de>>: Sized {
const SIZE: usize;
type Outputs;
fn unsatisfied_count(&self) -> usize;
fn open_count(&self) -> usize;
type RaceState;
fn init_race(&mut self, kp: KP) -> Self::RaceState;
#[allow(clippy::type_complexity)]
fn poll_race_one(
&mut self,
state: Pin<&mut Self::RaceState>,
arm_index: usize,
cx: &mut Context<'_>,
) -> Poll<Result<Probe<(usize, KP::KeyClaim)>, KP::Error>>;
type DispatchState;
fn init_dispatch(&mut self, arm_index: usize, vp: VP<'de, KP>) -> Self::DispatchState;
#[allow(clippy::type_complexity)]
fn poll_dispatch(
&mut self,
state: Pin<&mut Self::DispatchState>,
cx: &mut Context<'_>,
) -> Poll<Result<Probe<(VC<'de, KP>, ())>, KP::Error>>;
async fn race_keys(&mut self, kp: KP) -> Result<Probe<(usize, KP::KeyClaim)>, KP::Error> {
if Self::SIZE == 0 {
return Ok(Probe::Miss);
}
let mut race_state = core::pin::pin!(self.init_race(kp));
core::future::poll_fn(|cx| {
let mut all_miss = true;
for i in 0..Self::SIZE {
match self.poll_race_one(race_state.as_mut(), i, cx) {
Poll::Ready(Ok(Probe::Hit(v))) => return Poll::Ready(Ok(Probe::Hit(v))),
Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
Poll::Ready(Ok(Probe::Miss)) => {}
Poll::Pending => {
all_miss = false;
}
}
}
if all_miss {
return Poll::Ready(Ok(Probe::Miss));
}
Poll::Pending
})
.await
}
async fn dispatch_value(
&mut self,
arm_index: usize,
vp: VP<'de, KP>,
) -> Result<Probe<(VC<'de, KP>, ())>, KP::Error> {
let dispatch_state = self.init_dispatch(arm_index, vp);
let mut dispatch_state = core::pin::pin!(dispatch_state);
core::future::poll_fn(|cx| self.poll_dispatch(dispatch_state.as_mut(), cx)).await
}
fn take_outputs(&mut self) -> Self::Outputs;
}
impl<'de, KP: MapKeyProbe<'de>> MapArmStack<'de, KP> for MapArmBase {
const SIZE: usize = 0;
type Outputs = ();
#[inline(always)]
fn unsatisfied_count(&self) -> usize {
0
}
#[inline(always)]
fn open_count(&self) -> usize {
0
}
type RaceState = ();
#[inline(always)]
fn init_race(&mut self, _kp: KP) {}
#[inline(always)]
fn poll_race_one(
&mut self,
_state: Pin<&mut ()>,
_arm_index: usize,
_cx: &mut Context<'_>,
) -> Poll<Result<Probe<(usize, KP::KeyClaim)>, KP::Error>> {
unreachable!("poll_race_one called on MapArmBase (SIZE=0)")
}
type DispatchState = core::convert::Infallible;
#[inline(always)]
fn init_dispatch(&mut self, _arm_index: usize, _vp: VP<'de, KP>) -> Self::DispatchState {
unreachable!("init_dispatch called on MapArmBase")
}
#[inline(always)]
fn poll_dispatch(
&mut self,
_state: Pin<&mut Self::DispatchState>,
_cx: &mut Context<'_>,
) -> Poll<Result<Probe<(VC<'de, KP>, ())>, KP::Error>> {
unreachable!("poll_dispatch called on MapArmBase")
}
#[inline(always)]
fn take_outputs(&mut self) {}
}
impl<'de, KP, Rest, K, V, KeyFn, KeyFut, ValFn, ValFut> MapArmStack<'de, KP>
for (Rest, MapArmSlot<K, V, KeyFn, ValFn>)
where
KP: MapKeyProbe<'de>,
Rest: MapArmStack<'de, KP>,
KeyFn: FnMut(KP) -> KeyFut,
KeyFut: Future<Output = Result<Probe<(KP::KeyClaim, K)>, KP::Error>>,
ValFn: FnMut(VP<'de, KP>, K) -> ValFut,
ValFut: Future<Output = Result<Probe<(VC<'de, KP>, (K, V))>, KP::Error>>,
{
const SIZE: usize = Rest::SIZE + 1;
type Outputs = (Rest::Outputs, Option<(K, V)>);
#[inline(always)]
fn unsatisfied_count(&self) -> usize {
self.0.unsatisfied_count() + if self.1.state.is_done() { 0 } else { 1 }
}
#[inline(always)]
fn open_count(&self) -> usize {
self.0.open_count() + if self.1.state.is_done() { 0 } else { 1 }
}
type RaceState = SlotRaceState<Rest::RaceState, KeyFut>;
#[inline(always)]
fn init_race(&mut self, mut kp: KP) -> Self::RaceState {
let rest_kp = kp.fork();
let this_fut = if self.1.state.is_done() {
None
} else {
Some((self.1.key_fn)(kp))
};
SlotRaceState {
rest: self.0.init_race(rest_kp),
this: this_fut,
}
}
#[inline(always)]
fn poll_race_one(
&mut self,
state: Pin<&mut Self::RaceState>,
arm_index: usize,
cx: &mut Context<'_>,
) -> Poll<Result<Probe<(usize, KP::KeyClaim)>, KP::Error>> {
let projected = state.project();
if arm_index == Self::SIZE - 1 {
match poll_key_slot(projected.this, cx) {
Poll::Ready(Ok(Probe::Hit((kc, k)))) => {
self.1.state = ArmState::Key(k);
Poll::Ready(Ok(Probe::Hit((Self::SIZE - 1, kc))))
}
Poll::Ready(Ok(Probe::Miss)) => Poll::Ready(Ok(Probe::Miss)),
Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
Poll::Pending => Poll::Pending,
}
} else {
self.0.poll_race_one(projected.rest, arm_index, cx)
}
}
type DispatchState = SlotDispatchState<Rest::DispatchState, ValFut>;
#[inline(always)]
fn init_dispatch(&mut self, arm_index: usize, vp: VP<'de, KP>) -> Self::DispatchState {
if arm_index == Self::SIZE - 1 {
let k = match core::mem::replace(&mut self.1.state, ArmState::Empty) {
ArmState::Key(k) => k,
_ => unreachable!("init_dispatch called but arm not in Key state"),
};
SlotDispatchState::ThisArm((self.1.val_fn)(vp, k))
} else {
SlotDispatchState::Delegated(self.0.init_dispatch(arm_index, vp))
}
}
#[inline(always)]
fn poll_dispatch(
&mut self,
state: Pin<&mut Self::DispatchState>,
cx: &mut Context<'_>,
) -> Poll<Result<Probe<(VC<'de, KP>, ())>, KP::Error>> {
match state.project() {
SlotDispatchProj::ThisArm(fut) => fut.poll(cx).map(|r| {
r.map(|probe| match probe {
Probe::Hit((vc, (k, v))) => {
self.1.state = ArmState::Done(k, v);
Probe::Hit((vc, ()))
}
Probe::Miss => Probe::Miss,
})
}),
SlotDispatchProj::Delegated(rest_state) => self.0.poll_dispatch(rest_state, cx),
}
}
#[inline(always)]
fn take_outputs(&mut self) -> Self::Outputs {
let out = match mem::replace(&mut self.1.state, ArmState::Empty) {
ArmState::Done(k, v) => Some((k, v)),
_ => None,
};
(self.0.take_outputs(), out)
}
}
impl<'de, KP, Rest, K, KeyFn, KeyFut, ValFn, ValFut> MapArmStack<'de, KP>
for (Rest, VirtualArmSlot<K, KeyFn, ValFn>)
where
KP: MapKeyProbe<'de>,
Rest: MapArmStack<'de, KP>,
KeyFn: FnMut(KP) -> KeyFut,
KeyFut: Future<Output = Result<Probe<(KP::KeyClaim, K)>, KP::Error>>,
ValFn: FnMut(VP<'de, KP>, K) -> ValFut,
ValFut: Future<Output = Result<Probe<(VC<'de, KP>, ())>, KP::Error>>,
{
const SIZE: usize = Rest::SIZE + 1;
type Outputs = Rest::Outputs;
#[inline(always)]
fn unsatisfied_count(&self) -> usize {
self.0.unsatisfied_count()
}
#[inline(always)]
fn open_count(&self) -> usize {
self.0.open_count() + 1
}
type RaceState = SlotRaceState<Rest::RaceState, KeyFut>;
#[inline(always)]
fn init_race(&mut self, mut kp: KP) -> Self::RaceState {
let rest_kp = kp.fork();
let this_fut = (self.1.key_fn)(kp);
SlotRaceState {
rest: self.0.init_race(rest_kp),
this: Some(this_fut),
}
}
#[inline(always)]
fn poll_race_one(
&mut self,
state: Pin<&mut Self::RaceState>,
arm_index: usize,
cx: &mut Context<'_>,
) -> Poll<Result<Probe<(usize, KP::KeyClaim)>, KP::Error>> {
let projected = state.project();
if arm_index == Self::SIZE - 1 {
match poll_key_slot(projected.this, cx) {
Poll::Ready(Ok(Probe::Hit((kc, k)))) => {
self.1.pending_key = Some(k);
Poll::Ready(Ok(Probe::Hit((Self::SIZE - 1, kc))))
}
Poll::Ready(Ok(Probe::Miss)) => Poll::Ready(Ok(Probe::Miss)),
Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
Poll::Pending => Poll::Pending,
}
} else {
self.0.poll_race_one(projected.rest, arm_index, cx)
}
}
type DispatchState = SlotDispatchState<Rest::DispatchState, ValFut>;
#[inline(always)]
fn init_dispatch(&mut self, arm_index: usize, vp: VP<'de, KP>) -> Self::DispatchState {
if arm_index == Self::SIZE - 1 {
let k = self
.1
.pending_key
.take()
.expect("init_dispatch on virtual arm without pending key");
SlotDispatchState::ThisArm((self.1.val_fn)(vp, k))
} else {
SlotDispatchState::Delegated(self.0.init_dispatch(arm_index, vp))
}
}
#[inline(always)]
fn poll_dispatch(
&mut self,
state: Pin<&mut Self::DispatchState>,
cx: &mut Context<'_>,
) -> Poll<Result<Probe<(VC<'de, KP>, ())>, KP::Error>> {
match state.project() {
SlotDispatchProj::ThisArm(fut) => fut.poll(cx),
SlotDispatchProj::Delegated(rest_state) => self.0.poll_dispatch(rest_state, cx),
}
}
#[inline(always)]
fn take_outputs(&mut self) -> Self::Outputs {
self.0.take_outputs()
}
}
impl<'de, KP, S, const M: usize, KeyFn, KeyFut, SkipFn, SkipFut> MapArmStack<'de, KP>
for DetectDuplicatesOwned<S, M, KeyFn, SkipFn>
where
KP: MapKeyProbe<'de>,
S: MapArmStack<'de, KP>,
KeyFn: FnMut(KP) -> KeyFut,
KeyFut: Future<Output = Result<Probe<(KP::KeyClaim, crate::MatchVals<usize>)>, KP::Error>>,
SkipFn: FnMut(VP<'de, KP>) -> SkipFut,
SkipFut: Future<Output = Result<VC<'de, KP>, KP::Error>>,
{
const SIZE: usize = S::SIZE + 1;
type Outputs = S::Outputs;
#[inline(always)]
fn unsatisfied_count(&self) -> usize {
self.inner.unsatisfied_count()
}
#[inline(always)]
fn open_count(&self) -> usize {
self.inner.open_count() + 1
}
type RaceState = WrapperRaceState<S::RaceState, KeyFut>;
#[inline(always)]
fn init_race(&mut self, mut kp: KP) -> Self::RaceState {
let dup_kp = kp.fork();
let dup_fut = (self.key_fn)(dup_kp);
WrapperRaceState {
inner: self.inner.init_race(kp),
virtual_arm: Some(dup_fut),
}
}
#[inline(always)]
fn poll_race_one(
&mut self,
state: Pin<&mut Self::RaceState>,
arm_index: usize,
cx: &mut Context<'_>,
) -> Poll<Result<Probe<(usize, KP::KeyClaim)>, KP::Error>> {
let projected = state.project();
if arm_index == Self::SIZE - 1 {
match poll_key_slot(projected.virtual_arm, cx) {
Poll::Ready(Ok(Probe::Hit((kc, matched)))) => {
self.dup = self.wire_names[matched.0].0;
Poll::Ready(Ok(Probe::Hit((Self::SIZE - 1, kc))))
}
Poll::Ready(Ok(Probe::Miss)) => Poll::Ready(Ok(Probe::Miss)),
Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
Poll::Pending => Poll::Pending,
}
} else {
self.inner.poll_race_one(projected.inner, arm_index, cx)
}
}
type DispatchState = WrapperDispatchState<S::DispatchState, SkipFut>;
#[inline(always)]
fn init_dispatch(&mut self, arm_index: usize, vp: VP<'de, KP>) -> Self::DispatchState {
if arm_index == Self::SIZE - 1 {
WrapperDispatchState::Virtual((self.skip_fn)(vp))
} else {
WrapperDispatchState::Inner(self.inner.init_dispatch(arm_index, vp))
}
}
#[inline(always)]
fn poll_dispatch(
&mut self,
state: Pin<&mut Self::DispatchState>,
cx: &mut Context<'_>,
) -> Poll<Result<Probe<(VC<'de, KP>, ())>, KP::Error>> {
match state.project() {
WrapperDispatchProj::Virtual(fut) => fut.poll(cx).map(|r| match r {
Ok(_vc) => Err(<KP::Error as crate::DeserializeError>::duplicate_field(
self.dup,
)),
Err(e) => Err(e),
}),
WrapperDispatchProj::Inner(inner_state) => self.inner.poll_dispatch(inner_state, cx),
}
}
#[inline(always)]
fn take_outputs(&mut self) -> Self::Outputs {
self.inner.take_outputs()
}
}
impl<'de, 'v, KP, S, const N: usize, TagKeyFn, TagKeyFut, TagValFn, TagValFut> MapArmStack<'de, KP>
for TagInjectingStackOwned<'v, S, N, TagKeyFn, TagValFn>
where
KP: MapKeyProbe<'de>,
S: MapArmStack<'de, KP>,
TagKeyFn: FnMut(KP) -> TagKeyFut,
TagKeyFut: Future<Output = Result<Probe<(KP::KeyClaim, crate::Match)>, KP::Error>>,
TagValFn: FnMut(VP<'de, KP>) -> TagValFut,
TagValFut: Future<Output = Result<Probe<(VC<'de, KP>, crate::MatchVals<usize>)>, KP::Error>>,
{
const SIZE: usize = S::SIZE + 1;
type Outputs = S::Outputs;
#[inline(always)]
fn unsatisfied_count(&self) -> usize {
self.inner.unsatisfied_count()
}
#[inline(always)]
fn open_count(&self) -> usize {
self.inner.open_count() + 1
}
type RaceState = TagRaceState<TagKeyFut, S::RaceState>;
#[inline(always)]
fn init_race(&mut self, mut kp: KP) -> Self::RaceState {
let inner_kp = kp.fork();
let tag_fut = (self.tag_key_fn)(kp);
TagRaceState {
tag_fut: Some(tag_fut),
inner: self.inner.init_race(inner_kp),
}
}
#[inline(always)]
fn poll_race_one(
&mut self,
state: Pin<&mut Self::RaceState>,
arm_index: usize,
cx: &mut Context<'_>,
) -> Poll<Result<Probe<(usize, KP::KeyClaim)>, KP::Error>> {
let projected = state.project();
if arm_index == 0 {
match poll_key_slot(projected.tag_fut, cx) {
Poll::Ready(Ok(Probe::Hit((kc, _match)))) => Poll::Ready(Ok(Probe::Hit((0, kc)))),
Poll::Ready(Ok(Probe::Miss)) => Poll::Ready(Ok(Probe::Miss)),
Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
Poll::Pending => Poll::Pending,
}
} else {
match self.inner.poll_race_one(projected.inner, arm_index - 1, cx) {
Poll::Ready(Ok(Probe::Hit((idx, kc)))) => {
Poll::Ready(Ok(Probe::Hit((idx + 1, kc))))
}
other => other,
}
}
}
type DispatchState = TagDispatchState<TagValFut, S::DispatchState>;
#[inline(always)]
fn init_dispatch(&mut self, arm_index: usize, vp: VP<'de, KP>) -> Self::DispatchState {
if arm_index == 0 {
TagDispatchState::Tag((self.tag_val_fn)(vp))
} else {
TagDispatchState::Inner(self.inner.init_dispatch(arm_index - 1, vp))
}
}
#[inline(always)]
fn poll_dispatch(
&mut self,
state: Pin<&mut Self::DispatchState>,
cx: &mut Context<'_>,
) -> Poll<Result<Probe<(VC<'de, KP>, ())>, KP::Error>> {
match state.project() {
TagDispatchProj::Tag(fut) => fut.poll(cx).map(|r| {
r.map(|probe| match probe {
Probe::Hit((vc, crate::MatchVals(idx))) => {
self.tag_value.set(Some(idx));
Probe::Hit((vc, ()))
}
Probe::Miss => Probe::Miss,
})
}),
TagDispatchProj::Inner(inner_state) => self.inner.poll_dispatch(inner_state, cx),
}
}
#[inline(always)]
fn take_outputs(&mut self) -> Self::Outputs {
self.inner.take_outputs()
}
}
impl<'de, KP, A, B> MapArmStack<'de, KP> for StackConcat<A, B>
where
KP: MapKeyProbe<'de>,
A: MapArmStack<'de, KP>,
B: MapArmStack<'de, KP>,
{
const SIZE: usize = A::SIZE + B::SIZE;
type Outputs = (A::Outputs, B::Outputs);
#[inline(always)]
fn unsatisfied_count(&self) -> usize {
self.0.unsatisfied_count() + self.1.unsatisfied_count()
}
#[inline(always)]
fn open_count(&self) -> usize {
self.0.open_count() + self.1.open_count()
}
type RaceState = ConcatRaceState<A::RaceState, B::RaceState>;
#[inline(always)]
fn init_race(&mut self, mut kp: KP) -> Self::RaceState {
let b_kp = kp.fork();
ConcatRaceState {
a: self.0.init_race(kp),
b: self.1.init_race(b_kp),
}
}
#[inline(always)]
fn poll_race_one(
&mut self,
state: Pin<&mut Self::RaceState>,
arm_index: usize,
cx: &mut Context<'_>,
) -> Poll<Result<Probe<(usize, KP::KeyClaim)>, KP::Error>> {
let projected = state.project();
if arm_index < A::SIZE {
self.0.poll_race_one(projected.a, arm_index, cx)
} else {
match self.1.poll_race_one(projected.b, arm_index - A::SIZE, cx) {
Poll::Ready(Ok(Probe::Hit((idx, kc)))) => {
Poll::Ready(Ok(Probe::Hit((A::SIZE + idx, kc))))
}
other => other,
}
}
}
type DispatchState = ConcatDispatchState<A::DispatchState, B::DispatchState>;
#[inline(always)]
fn init_dispatch(&mut self, arm_index: usize, vp: VP<'de, KP>) -> Self::DispatchState {
if arm_index < A::SIZE {
ConcatDispatchState::InA(self.0.init_dispatch(arm_index, vp))
} else {
ConcatDispatchState::InB(self.1.init_dispatch(arm_index - A::SIZE, vp))
}
}
#[inline(always)]
fn poll_dispatch(
&mut self,
state: Pin<&mut Self::DispatchState>,
cx: &mut Context<'_>,
) -> Poll<Result<Probe<(VC<'de, KP>, ())>, KP::Error>> {
match state.project() {
ConcatDispatchProj::InA(a_state) => self.0.poll_dispatch(a_state, cx),
ConcatDispatchProj::InB(b_state) => self.1.poll_dispatch(b_state, cx),
}
}
#[inline(always)]
fn take_outputs(&mut self) -> Self::Outputs {
(self.0.take_outputs(), self.1.take_outputs())
}
}
#[allow(async_fn_in_trait)]
pub trait FlattenCont<'de, M: MapAccess<'de>> {
type Extra;
async fn finish<Arms: MapArmStack<'de, M::KeyProbe>>(
self,
map: M,
arms: Arms,
) -> Result<Probe<(M::MapClaim, Arms::Outputs, Self::Extra)>, M::Error>;
}
impl<'de, M: MapAccess<'de>> FlattenCont<'de, M> for crate::FlattenTerminal {
type Extra = ();
async fn finish<Arms: MapArmStack<'de, M::KeyProbe>>(
self,
map: M,
arms: Arms,
) -> Result<Probe<(M::MapClaim, Arms::Outputs, ())>, M::Error> {
let wrapped = crate::SkipUnknown!(arms, M::KeyProbe, VP<'de, M::KeyProbe>);
let (claim, out) = crate::hit!(map.iterate(wrapped).await);
Ok(Probe::Hit((claim, out, ())))
}
}
#[cfg(feature = "alloc")]
impl<'de, M: MapAccess<'de>> FlattenCont<'de, M> for crate::FlattenTerminalBoxed {
type Extra = ();
async fn finish<Arms: MapArmStack<'de, M::KeyProbe>>(
self,
map: M,
arms: Arms,
) -> Result<Probe<(M::MapClaim, Arms::Outputs, ())>, M::Error> {
let wrapped = crate::SkipUnknown!(arms, M::KeyProbe, VP<'de, M::KeyProbe>);
#[allow(clippy::type_complexity)]
let r: Result<Probe<(M::MapClaim, Arms::Outputs)>, M::Error> =
alloc::boxed::Box::pin(map.iterate(wrapped)).await;
let (claim, out) = crate::hit!(r);
Ok(Probe::Hit((claim, out, ())))
}
}
pub struct FlattenDeserializer<'a, 'de, M, OuterArms, Cont>
where
M: MapAccess<'de>,
OuterArms: MapArmStack<'de, M::KeyProbe>,
Cont: FlattenCont<'de, M>,
{
pub map: M,
pub outer_arms: &'a core::cell::Cell<Option<OuterArms>>,
pub outer_outputs: &'a core::cell::Cell<Option<OuterArms::Outputs>>,
pub cont: Cont,
pub extra: &'a core::cell::Cell<Option<Cont::Extra>>,
pub _de: core::marker::PhantomData<&'de ()>,
}
impl<'a, 'de, M, OuterArms, Cont> FlattenDeserializer<'a, 'de, M, OuterArms, Cont>
where
M: MapAccess<'de>,
OuterArms: MapArmStack<'de, M::KeyProbe>,
Cont: FlattenCont<'de, M>,
{
pub fn new(
map: M,
outer_arms: &'a core::cell::Cell<Option<OuterArms>>,
outer_outputs: &'a core::cell::Cell<Option<OuterArms::Outputs>>,
cont: Cont,
extra: &'a core::cell::Cell<Option<Cont::Extra>>,
) -> Self {
Self {
map,
outer_arms,
outer_outputs,
cont,
extra,
_de: core::marker::PhantomData,
}
}
}
impl<'a, 'de, M, OuterArms, Cont> Deserializer<'de>
for FlattenDeserializer<'a, 'de, M, OuterArms, Cont>
where
M: MapAccess<'de>,
OuterArms: MapArmStack<'de, M::KeyProbe>,
Cont: FlattenCont<'de, M>,
{
type Error = M::Error;
type Claim = M::MapClaim;
type EntryClaim = M::MapClaim;
type Entry = FlattenEntry<'a, 'de, M, OuterArms, Cont>;
async fn entry<const N: usize, F, Fut, R>(
self,
mut f: F,
) -> Result<Probe<(Self::Claim, R)>, Self::Error>
where
F: FnMut([Self::Entry; N]) -> Fut,
Fut: core::future::Future<Output = Result<Probe<(Self::EntryClaim, R)>, Self::Error>>,
{
assert!(N == 1, "FlattenDeserializer only supports entry<1, ...>");
let entry = FlattenEntry {
map: self.map,
outer_arms: self.outer_arms,
outer_outputs: self.outer_outputs,
cont: self.cont,
extra: self.extra,
_de: core::marker::PhantomData,
};
let mut slot = Some(entry);
let entries: [Self::Entry; N] = core::array::from_fn(|_| slot.take().unwrap());
f(entries).await
}
}
pub struct FlattenEntry<'a, 'de, M, OuterArms, Cont>
where
M: MapAccess<'de>,
OuterArms: MapArmStack<'de, M::KeyProbe>,
Cont: FlattenCont<'de, M>,
{
pub map: M,
pub outer_arms: &'a core::cell::Cell<Option<OuterArms>>,
pub outer_outputs: &'a core::cell::Cell<Option<OuterArms::Outputs>>,
pub cont: Cont,
pub extra: &'a core::cell::Cell<Option<Cont::Extra>>,
pub _de: core::marker::PhantomData<&'de ()>,
}
impl<'a, 'de, M, OuterArms, Cont> Entry<'de> for FlattenEntry<'a, 'de, M, OuterArms, Cont>
where
M: MapAccess<'de>,
OuterArms: MapArmStack<'de, M::KeyProbe>,
Cont: FlattenCont<'de, M>,
{
type Error = M::Error;
type Claim = M::MapClaim;
type StrChunks = crate::Never<'static, M::MapClaim, M::Error>;
type BytesChunks = crate::Never<'static, M::MapClaim, M::Error>;
type Map = FlattenMapAccess<'a, 'de, M, OuterArms, Cont>;
type Seq = crate::Never<'static, M::MapClaim, M::Error>;
async fn deserialize_map(self) -> Result<Probe<Self::Map>, Self::Error> {
Ok(Probe::Hit(FlattenMapAccess {
map: self.map,
outer_arms: self.outer_arms,
outer_outputs: self.outer_outputs,
cont: self.cont,
extra: self.extra,
_de: core::marker::PhantomData,
}))
}
async fn deserialize_bool(self) -> Result<Probe<(Self::Claim, bool)>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_u8(self) -> Result<Probe<(Self::Claim, u8)>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_u16(self) -> Result<Probe<(Self::Claim, u16)>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_u32(self) -> Result<Probe<(Self::Claim, u32)>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_u64(self) -> Result<Probe<(Self::Claim, u64)>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_u128(self) -> Result<Probe<(Self::Claim, u128)>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_i8(self) -> Result<Probe<(Self::Claim, i8)>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_i16(self) -> Result<Probe<(Self::Claim, i16)>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_i32(self) -> Result<Probe<(Self::Claim, i32)>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_i64(self) -> Result<Probe<(Self::Claim, i64)>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_i128(self) -> Result<Probe<(Self::Claim, i128)>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_f32(self) -> Result<Probe<(Self::Claim, f32)>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_f64(self) -> Result<Probe<(Self::Claim, f64)>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_char(self) -> Result<Probe<(Self::Claim, char)>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_str(self) -> Result<Probe<(Self::Claim, &'de str)>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_str_chunks(self) -> Result<Probe<Self::StrChunks>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_bytes(self) -> Result<Probe<(Self::Claim, &'de [u8])>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_bytes_chunks(self) -> Result<Probe<Self::BytesChunks>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_seq(self) -> Result<Probe<Self::Seq>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_null(self) -> Result<Probe<Self::Claim>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_option<T: Deserialize<'de, Extra>, Extra>(
self,
_extra: Extra,
) -> Result<Probe<(Self::Claim, Option<T>)>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_value<T: Deserialize<'de, Extra>, Extra>(
self,
_extra: Extra,
) -> Result<Probe<(Self::Claim, T)>, Self::Error> {
Ok(Probe::Miss)
}
fn fork(&mut self) -> Self {
panic!("FlattenEntry::fork called; flatten only supports N=1 entry")
}
async fn skip(self) -> Result<Self::Claim, Self::Error> {
panic!("FlattenEntry::skip called on flatten entry")
}
}
pub struct FlattenMapAccess<'a, 'de, M, OuterArms, Cont>
where
M: MapAccess<'de>,
OuterArms: MapArmStack<'de, M::KeyProbe>,
Cont: FlattenCont<'de, M>,
{
pub map: M,
pub outer_arms: &'a core::cell::Cell<Option<OuterArms>>,
pub outer_outputs: &'a core::cell::Cell<Option<OuterArms::Outputs>>,
pub cont: Cont,
pub extra: &'a core::cell::Cell<Option<Cont::Extra>>,
pub _de: core::marker::PhantomData<&'de ()>,
}
impl<'a, 'de, M, OuterArms, Cont> MapAccess<'de> for FlattenMapAccess<'a, 'de, M, OuterArms, Cont>
where
M: MapAccess<'de>,
OuterArms: MapArmStack<'de, M::KeyProbe>,
Cont: FlattenCont<'de, M>,
{
type Error = M::Error;
type MapClaim = M::MapClaim;
type KeyProbe = M::KeyProbe;
fn fork(&mut self) -> Self {
panic!("FlattenMapAccess::fork not supported")
}
async fn iterate<S: MapArmStack<'de, Self::KeyProbe>>(
self,
inner_arms: S,
) -> Result<Probe<(Self::MapClaim, S::Outputs)>, Self::Error> {
let outer_arms = self
.outer_arms
.take()
.expect("FlattenMapAccess::iterate called without outer arms");
let combined = StackConcat(outer_arms, inner_arms);
let (claim, (outer_out, inner_out), extra) =
crate::hit!(self.cont.finish(self.map, combined).await);
self.outer_outputs.set(Some(outer_out));
self.extra.set(Some(extra));
Ok(Probe::Hit((claim, inner_out)))
}
}
#[macro_export]
macro_rules! SkipUnknown {
($inner:expr, $kp:ty, $vp:ty) => {{
use $crate::MapKeyProbe as _;
(
$inner,
$crate::VirtualArmSlot::new(
|kp: $kp| kp.deserialize_key::<$crate::Skip, _>(()),
|vp: $vp, _k: $crate::Skip| async move {
use $crate::MapValueProbe as _;
let vc = vp.skip().await?;
::core::result::Result::Ok($crate::Probe::Hit((vc, ())))
},
),
)
}};
($inner:expr) => {{
use $crate::MapKeyProbe as _;
(
$inner,
$crate::VirtualArmSlot::new(
|kp| kp.deserialize_key::<$crate::Skip, _>(()),
|vp, _k: $crate::Skip| async move {
use $crate::MapValueProbe as _;
let vc = vp.skip().await?;
::core::result::Result::Ok($crate::Probe::Hit((vc, ())))
},
),
)
}};
}
#[macro_export]
macro_rules! DetectDuplicates {
($inner:expr, $wire_names:expr, $kp:ty, $vp:ty) => {{
use $crate::MapKeyProbe as _;
let __wn = $wire_names;
$crate::DetectDuplicatesOwned::new(
$inner,
__wn,
move |kp: $kp| kp.deserialize_key::<$crate::MatchVals<usize>, _>(__wn),
|vp: $vp| vp.skip(),
)
}};
}
#[macro_export]
macro_rules! TagInjectingStack {
($inner:expr, $tag_field:expr, $tag_candidates:expr, $tag_value:expr, $kp:ty, $vp:ty) => {{
use $crate::MapKeyProbe as _;
use $crate::MapValueProbe as _;
let __tf = $tag_field;
let __tc = $tag_candidates;
$crate::TagInjectingStackOwned::new(
$inner,
__tf,
__tc,
$tag_value,
move |kp: $kp| kp.deserialize_key::<$crate::Match, &str>(__tf),
move |vp: $vp| vp.deserialize_value::<$crate::MatchVals<usize>, _>(__tc),
)
}};
}
pub trait SeqAccess<'de>: Sized {
type Error: DeserializeError;
type SeqClaim: 'de;
type ElemClaim: 'de;
type Elem: SeqEntry<'de, Claim = Self::ElemClaim, Error = Self::Error>;
fn fork(&mut self) -> Self;
async fn next<const N: usize, F, Fut, R>(
self,
f: F,
) -> Result<Probe<Chunk<(Self, R), Self::SeqClaim>>, Self::Error>
where
F: FnMut([Self::Elem; N]) -> Fut,
Fut: Future<Output = Result<Probe<(Self::ElemClaim, R)>, Self::Error>>;
}
pub trait SeqEntry<'de> {
type Error: DeserializeError;
type Claim: 'de;
async fn get<T: Deserialize<'de, Extra>, Extra>(
self,
extra: Extra,
) -> Result<Probe<(Self::Claim, T)>, Self::Error>;
fn fork(&mut self) -> Self
where
Self: Sized;
async fn skip(self) -> Result<Self::Claim, Self::Error>;
}
impl<'n, C, E: DeserializeError> StrAccess for crate::Never<'n, C, E> {
type Claim = C;
type Error = E;
fn fork(&mut self) -> Self {
match self.0 {}
}
async fn next_str<R>(
self,
_f: impl FnOnce(&str) -> R,
) -> Result<Chunk<(Self, R), Self::Claim>, Self::Error> {
match self.0 {}
}
}
impl<'n, C, E: DeserializeError> BytesAccess for crate::Never<'n, C, E> {
type Claim = C;
type Error = E;
fn fork(&mut self) -> Self {
match self.0 {}
}
async fn next_bytes<R>(
self,
_f: impl FnOnce(&[u8]) -> R,
) -> Result<Chunk<(Self, R), Self::Claim>, Self::Error> {
match self.0 {}
}
}
impl<'n, 'de, C: 'de, E: DeserializeError> SeqAccess<'de> for crate::Never<'n, C, E> {
type Error = E;
type SeqClaim = C;
type ElemClaim = C;
type Elem = crate::Never<'n, C, E>;
fn fork(&mut self) -> Self {
match self.0 {}
}
async fn next<const N: usize, F, Fut, R>(
self,
_f: F,
) -> Result<Probe<Chunk<(Self, R), Self::SeqClaim>>, Self::Error>
where
F: FnMut([Self::Elem; N]) -> Fut,
Fut: core::future::Future<Output = Result<Probe<(Self::ElemClaim, R)>, Self::Error>>,
{
match self.0 {}
}
}
impl<'n, 'de, C: 'de, E: DeserializeError> SeqEntry<'de> for crate::Never<'n, C, E> {
type Error = E;
type Claim = C;
fn fork(&mut self) -> Self {
match self.0 {}
}
async fn get<T: Deserialize<'de, Extra>, Extra>(
self,
_extra: Extra,
) -> Result<Probe<(Self::Claim, T)>, Self::Error> {
match self.0 {}
}
async fn skip(self) -> Result<Self::Claim, Self::Error> {
match self.0 {}
}
}
impl<'n, 'de, C: 'de, E: DeserializeError> MapAccess<'de> for crate::Never<'n, C, E> {
type Error = E;
type MapClaim = C;
type KeyProbe = crate::Never<'n, C, E>;
fn fork(&mut self) -> Self {
match self.0 {}
}
async fn iterate<S: MapArmStack<'de, Self::KeyProbe>>(
self,
_arms: S,
) -> Result<Probe<(Self::MapClaim, S::Outputs)>, Self::Error> {
match self.0 {}
}
}
impl<'n, 'de, C: 'de, E: DeserializeError> MapKeyProbe<'de> for crate::Never<'n, C, E> {
type Error = E;
type KeyClaim = crate::Never<'n, C, E>;
fn fork(&mut self) -> Self {
match self.0 {}
}
async fn deserialize_key<K: Deserialize<'de, Extra>, Extra>(
self,
_extra: Extra,
) -> Result<Probe<(Self::KeyClaim, K)>, Self::Error> {
match self.0 {}
}
}
impl<'n, 'de, C: 'de, E: DeserializeError> MapKeyClaim<'de> for crate::Never<'n, C, E> {
type Error = E;
type MapClaim = C;
type ValueProbe = crate::Never<'n, C, E>;
async fn into_value_probe(self) -> Result<Self::ValueProbe, Self::Error> {
match self.0 {}
}
}
impl<'n, 'de, C: 'de, E: DeserializeError> MapValueProbe<'de> for crate::Never<'n, C, E> {
type Error = E;
type MapClaim = C;
type ValueClaim = crate::Never<'n, C, E>;
fn fork(&mut self) -> Self {
match self.0 {}
}
async fn deserialize_value<V: Deserialize<'de, Extra>, Extra>(
self,
_extra: Extra,
) -> Result<Probe<(Self::ValueClaim, V)>, Self::Error> {
match self.0 {}
}
async fn skip(self) -> Result<Self::ValueClaim, Self::Error> {
match self.0 {}
}
}
impl<'n, 'de, C: 'de, E: DeserializeError> MapValueClaim<'de> for crate::Never<'n, C, E> {
type Error = E;
type KeyProbe = crate::Never<'n, C, E>;
type MapClaim = C;
async fn next_key(
self,
_unsatisfied: usize,
_open: usize,
) -> Result<NextKey<Self::KeyProbe, Self::MapClaim>, Self::Error> {
match self.0 {}
}
}
macro_rules! impl_deserialize_primitive {
($ty:ty, $method:ident) => {
impl<'de> Deserialize<'de> for $ty {
async fn deserialize<D: Deserializer<'de>>(
d: D,
_extra: (),
) -> Result<Probe<(D::Claim, Self)>, D::Error> {
d.entry(|[e]| async { e.$method().await }).await
}
}
};
}
impl_deserialize_primitive!(bool, deserialize_bool);
impl_deserialize_primitive!(u8, deserialize_u8);
impl_deserialize_primitive!(u16, deserialize_u16);
impl_deserialize_primitive!(u32, deserialize_u32);
impl_deserialize_primitive!(u64, deserialize_u64);
impl_deserialize_primitive!(u128, deserialize_u128);
impl_deserialize_primitive!(i8, deserialize_i8);
impl_deserialize_primitive!(i16, deserialize_i16);
impl_deserialize_primitive!(i32, deserialize_i32);
impl_deserialize_primitive!(i64, deserialize_i64);
impl_deserialize_primitive!(i128, deserialize_i128);
impl_deserialize_primitive!(f32, deserialize_f32);
impl_deserialize_primitive!(f64, deserialize_f64);
impl_deserialize_primitive!(char, deserialize_char);
impl<'de: 'a, 'a> Deserialize<'de> for &'a str {
async fn deserialize<D: Deserializer<'de>>(
d: D,
_extra: (),
) -> Result<Probe<(D::Claim, Self)>, D::Error> {
d.entry(|[e]| e.deserialize_str()).await
}
}
impl<'de: 'a, 'a> Deserialize<'de> for &'a [u8] {
async fn deserialize<D: Deserializer<'de>>(
d: D,
_extra: (),
) -> Result<Probe<(D::Claim, Self)>, D::Error> {
d.entry(|[e]| e.deserialize_bytes()).await
}
}
impl<'de, Extra: Copy, T: Deserialize<'de, Extra>> Deserialize<'de, Extra> for Option<T> {
async fn deserialize<D: Deserializer<'de>>(
d: D,
extra: Extra,
) -> Result<Probe<(D::Claim, Self)>, D::Error> {
d.entry(|[e]| e.deserialize_option::<T, Extra>(extra)).await
}
}