use core::future::Future;
use core::mem;
use core::pin::Pin;
use core::task::{Context, Poll};
pub use crate::map_arm::{
ArmState, ConcatDispatchState, ConcatRaceState, DetectDuplicatesOwned, MapArm, MapArmBase,
MapArmSlot, NextKey, SlotDispatchState, SlotRaceState, StackConcat, TagDispatchState,
TagInjectingStackOwned, TagRaceState, VirtualArmSlot, WrapperDispatchState, WrapperRaceState,
};
use crate::map_arm::{
ConcatDispatchProj, SlotDispatchProj, TagDispatchProj, WrapperDispatchProj, poll_key_slot,
};
use crate::{Chunk, DeserializeError, Probe, hit};
pub trait DeserializeOwned<Extra = ()>: Sized {
async fn deserialize_owned<D: DeserializerOwned>(
d: D,
extra: Extra,
) -> Result<Probe<(D::Claim, Self)>, D::Error>;
}
pub trait DeserializerOwned: Sized {
type Error: DeserializeError;
type Claim;
type EntryClaim;
type Entry: EntryOwned<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 EntryOwned: Sized {
type Error: DeserializeError;
type Claim;
type StrChunks: StrAccessOwned<Claim = Self::Claim, Error = Self::Error>;
type BytesChunks: BytesAccessOwned<Claim = Self::Claim, Error = Self::Error>;
type Map: MapAccessOwned<MapClaim = Self::Claim, Error = Self::Error>;
type Seq: SeqAccessOwned<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_chunks(self) -> Result<Probe<Self::StrChunks>, 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: DeserializeOwned<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: DeserializeOwned<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 StrAccessOwned: 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 BytesAccessOwned: 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 SeqAccessOwned: Sized {
type Error: DeserializeError;
type SeqClaim;
type ElemClaim;
type Elem: SeqEntryOwned<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 SeqEntryOwned {
type Error: DeserializeError;
type Claim;
fn fork(&mut self) -> Self
where
Self: Sized;
async fn get<T: DeserializeOwned<Extra>, Extra>(
self,
extra: Extra,
) -> Result<Probe<(Self::Claim, T)>, Self::Error>;
async fn skip(self) -> Result<Self::Claim, Self::Error>;
}
pub trait MapKeyProbeOwned: Sized {
type Error: DeserializeError;
type KeyClaim: MapKeyClaimOwned<Error = Self::Error>;
fn fork(&mut self) -> Self;
async fn deserialize_key<K: DeserializeOwned<Extra>, Extra>(
self,
extra: Extra,
) -> Result<Probe<(Self::KeyClaim, K)>, Self::Error>;
}
pub trait MapKeyClaimOwned: Sized {
type Error: DeserializeError;
type MapClaim;
type ValueProbe: MapValueProbeOwned<MapClaim = Self::MapClaim, Error = Self::Error>;
async fn into_value_probe(self) -> Result<Self::ValueProbe, Self::Error>;
}
pub trait MapValueProbeOwned: Sized {
type Error: DeserializeError;
type MapClaim;
type ValueClaim: MapValueClaimOwned<MapClaim = Self::MapClaim, Error = Self::Error>;
fn fork(&mut self) -> Self;
async fn deserialize_value<V: DeserializeOwned<Extra>, Extra>(
self,
extra: Extra,
) -> Result<Probe<(Self::ValueClaim, V)>, Self::Error>;
async fn skip(self) -> Result<Self::ValueClaim, Self::Error>;
}
pub trait MapValueClaimOwned: Sized {
type Error: DeserializeError;
type KeyProbe: MapKeyProbeOwned<Error = Self::Error>;
type MapClaim;
async fn next_key(
self,
unsatisfied: usize,
open: usize,
) -> Result<NextKey<Self::KeyProbe, Self::MapClaim>, Self::Error>;
}
pub type KP<D> = <<<D as DeserializerOwned>::Entry as EntryOwned>::Map as MapAccessOwned>::KeyProbe;
pub type VC<KP> = <<<KP as MapKeyProbeOwned>::KeyClaim as MapKeyClaimOwned>::ValueProbe as MapValueProbeOwned>::ValueClaim;
pub type VP<KP> = <<KP as MapKeyProbeOwned>::KeyClaim as MapKeyClaimOwned>::ValueProbe;
pub type VP2<D> = <<KP<D> as MapKeyProbeOwned>::KeyClaim as MapKeyClaimOwned>::ValueProbe;
pub trait MapArmStackOwned<KP: MapKeyProbeOwned>: 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<KP>) -> Self::DispatchState;
#[allow(clippy::type_complexity)]
fn poll_dispatch(
&mut self,
state: Pin<&mut Self::DispatchState>,
cx: &mut Context<'_>,
) -> Poll<Result<Probe<(VC<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<KP>,
) -> Result<Probe<(VC<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<KP: MapKeyProbeOwned> MapArmStackOwned<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<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<KP>, ())>, KP::Error>> {
unreachable!("poll_dispatch called on MapArmBase")
}
#[inline(always)]
fn take_outputs(&mut self) {}
}
impl<KP, Rest, K, V, KeyFn, KeyFut, ValFn, ValFut> MapArmStackOwned<KP>
for (Rest, MapArmSlot<K, V, KeyFn, ValFn>)
where
KP: MapKeyProbeOwned,
Rest: MapArmStackOwned<KP>,
KeyFn: FnMut(KP) -> KeyFut,
KeyFut: Future<Output = Result<Probe<(KP::KeyClaim, K)>, KP::Error>>,
ValFn: FnMut(VP<KP>, K) -> ValFut,
ValFut: Future<Output = Result<Probe<(VC<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<KP>) -> Self::DispatchState {
if arm_index == Self::SIZE - 1 {
let k = match 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<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<KP, Rest, K, KeyFn, KeyFut, ValFn, ValFut> MapArmStackOwned<KP>
for (Rest, VirtualArmSlot<K, KeyFn, ValFn>)
where
KP: MapKeyProbeOwned,
Rest: MapArmStackOwned<KP>,
KeyFn: FnMut(KP) -> KeyFut,
KeyFut: Future<Output = Result<Probe<(KP::KeyClaim, K)>, KP::Error>>,
ValFn: FnMut(VP<KP>, K) -> ValFut,
ValFut: Future<Output = Result<Probe<(VC<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<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<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()
}
}
#[macro_export]
macro_rules! SkipUnknownOwned {
($inner:expr, $kp:ty, $vp:ty) => {{
use $crate::MapKeyProbeOwned as _;
(
$inner,
$crate::VirtualArmSlot::new(
|kp: $kp| kp.deserialize_key::<$crate::Skip, _>(()),
|vp: $vp, _k: $crate::Skip| async move {
use $crate::MapValueProbeOwned as _;
let vc = vp.skip().await?;
::core::result::Result::Ok($crate::Probe::Hit((vc, ())))
},
),
)
}};
($inner:expr) => {{
use $crate::MapKeyProbeOwned as _;
(
$inner,
$crate::VirtualArmSlot::new(
|kp| kp.deserialize_key::<$crate::Skip, _>(()),
|vp, _k: $crate::Skip| async move {
use $crate::MapValueProbeOwned as _;
let vc = vp.skip().await?;
::core::result::Result::Ok($crate::Probe::Hit((vc, ())))
},
),
)
}};
}
impl<KP, S, const M: usize, KeyFn, KeyFut, SkipFn, SkipFut> MapArmStackOwned<KP>
for DetectDuplicatesOwned<S, M, KeyFn, SkipFn>
where
KP: MapKeyProbeOwned,
S: MapArmStackOwned<KP>,
KeyFn: FnMut(KP) -> KeyFut,
KeyFut: Future<Output = Result<Probe<(KP::KeyClaim, crate::MatchVals<usize>)>, KP::Error>>,
SkipFn: FnMut(VP<KP>) -> SkipFut,
SkipFut: Future<Output = Result<VC<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<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<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()
}
}
#[macro_export]
macro_rules! DetectDuplicatesOwned {
($inner:expr, $wire_names:expr, $kp:ty, $vp:ty) => {{
use $crate::MapKeyProbeOwned as _;
use $crate::MapValueProbeOwned as _;
let __wn = $wire_names;
$crate::DetectDuplicatesOwned::new(
$inner,
__wn,
move |kp: $kp| kp.deserialize_key::<$crate::MatchVals<usize>, _>(__wn),
|vp: $vp| vp.skip(),
)
}};
}
impl<'v, KP, S, const N: usize, TagKeyFn, TagKeyFut, TagValFn, TagValFut> MapArmStackOwned<KP>
for TagInjectingStackOwned<'v, S, N, TagKeyFn, TagValFn>
where
KP: MapKeyProbeOwned,
S: MapArmStackOwned<KP>,
TagKeyFn: FnMut(KP) -> TagKeyFut,
TagKeyFut: Future<Output = Result<Probe<(KP::KeyClaim, crate::Match)>, KP::Error>>,
TagValFn: FnMut(VP<KP>) -> TagValFut,
TagValFut: Future<Output = Result<Probe<(VC<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<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<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()
}
}
#[macro_export]
macro_rules! TagInjectingStackOwned {
($inner:expr, $tag_field:expr, $tag_candidates:expr, $tag_value:expr, $kp:ty, $vp:ty) => {{
use $crate::MapKeyProbeOwned as _;
use $crate::MapValueProbeOwned 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),
)
}};
}
impl<KP, A, B> MapArmStackOwned<KP> for StackConcat<A, B>
where
KP: MapKeyProbeOwned,
A: MapArmStackOwned<KP>,
B: MapArmStackOwned<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<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<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 FlattenContOwned<M: MapAccessOwned> {
type Extra;
async fn finish<Arms: MapArmStackOwned<M::KeyProbe>>(
self,
map: M,
arms: Arms,
) -> Result<Probe<(M::MapClaim, Arms::Outputs, Self::Extra)>, M::Error>;
}
impl<M: MapAccessOwned> FlattenContOwned<M> for crate::FlattenTerminal {
type Extra = ();
async fn finish<Arms: MapArmStackOwned<M::KeyProbe>>(
self,
map: M,
arms: Arms,
) -> Result<Probe<(M::MapClaim, Arms::Outputs, ())>, M::Error> {
let wrapped = crate::SkipUnknownOwned!(arms, M::KeyProbe, VP<M::KeyProbe>);
let (claim, out) = hit!(map.iterate(wrapped).await);
Ok(Probe::Hit((claim, out, ())))
}
}
#[cfg(feature = "alloc")]
impl<M: MapAccessOwned> FlattenContOwned<M> for crate::FlattenTerminalBoxed {
type Extra = ();
async fn finish<Arms: MapArmStackOwned<M::KeyProbe>>(
self,
map: M,
arms: Arms,
) -> Result<Probe<(M::MapClaim, Arms::Outputs, ())>, M::Error> {
let wrapped = crate::SkipUnknownOwned!(arms, M::KeyProbe, VP<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) = hit!(r);
Ok(Probe::Hit((claim, out, ())))
}
}
pub struct FlattenDeserializerOwned<'a, M, OuterArms, Cont>
where
M: MapAccessOwned,
OuterArms: MapArmStackOwned<M::KeyProbe>,
Cont: FlattenContOwned<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>>,
}
impl<'a, M, OuterArms, Cont> FlattenDeserializerOwned<'a, M, OuterArms, Cont>
where
M: MapAccessOwned,
OuterArms: MapArmStackOwned<M::KeyProbe>,
Cont: FlattenContOwned<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,
}
}
}
impl<'a, M, OuterArms, Cont> DeserializerOwned for FlattenDeserializerOwned<'a, M, OuterArms, Cont>
where
M: MapAccessOwned,
OuterArms: MapArmStackOwned<M::KeyProbe>,
Cont: FlattenContOwned<M>,
{
type Error = M::Error;
type Claim = M::MapClaim;
type EntryClaim = M::MapClaim;
type Entry = FlattenEntryOwned<'a, 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::Entry as EntryOwned>::Claim, R)>, Self::Error>,
>,
{
assert!(
N == 1,
"FlattenDeserializerOwned only supports entry<1, ...>"
);
let entry = FlattenEntryOwned {
map: self.map,
outer_arms: self.outer_arms,
outer_outputs: self.outer_outputs,
cont: self.cont,
extra: self.extra,
};
let mut slot = Some(entry);
let entries: [Self::Entry; N] = core::array::from_fn(|_| slot.take().unwrap());
f(entries).await
}
}
pub struct FlattenEntryOwned<'a, M, OuterArms, Cont>
where
M: MapAccessOwned,
OuterArms: MapArmStackOwned<M::KeyProbe>,
Cont: FlattenContOwned<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>>,
}
impl<'a, M, OuterArms, Cont> EntryOwned for FlattenEntryOwned<'a, M, OuterArms, Cont>
where
M: MapAccessOwned,
OuterArms: MapArmStackOwned<M::KeyProbe>,
Cont: FlattenContOwned<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 = FlattenMapAccessOwned<'a, 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(FlattenMapAccessOwned {
map: self.map,
outer_arms: self.outer_arms,
outer_outputs: self.outer_outputs,
cont: self.cont,
extra: self.extra,
}))
}
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_chunks(self) -> Result<Probe<Self::StrChunks>, 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: DeserializeOwned<Extra>, Extra>(
self,
_extra: Extra,
) -> Result<Probe<(Self::Claim, Option<T>)>, Self::Error> {
Ok(Probe::Miss)
}
async fn deserialize_value<T: DeserializeOwned<Extra>, Extra>(
self,
_extra: Extra,
) -> Result<Probe<(Self::Claim, T)>, Self::Error> {
Ok(Probe::Miss)
}
fn fork(&mut self) -> Self {
panic!("FlattenEntryOwned::fork called; flatten only supports N=1 entry")
}
async fn skip(self) -> Result<Self::Claim, Self::Error> {
panic!("FlattenEntryOwned::skip called on flatten entry")
}
}
pub struct FlattenMapAccessOwned<'a, M, OuterArms, Cont>
where
M: MapAccessOwned,
OuterArms: MapArmStackOwned<M::KeyProbe>,
Cont: FlattenContOwned<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>>,
}
impl<'a, M, OuterArms, Cont> MapAccessOwned for FlattenMapAccessOwned<'a, M, OuterArms, Cont>
where
M: MapAccessOwned,
OuterArms: MapArmStackOwned<M::KeyProbe>,
Cont: FlattenContOwned<M>,
{
type Error = M::Error;
type MapClaim = M::MapClaim;
type KeyProbe = M::KeyProbe;
fn fork(&mut self) -> Self {
panic!("FlattenMapAccessOwned::fork not supported")
}
async fn iterate<S: MapArmStackOwned<Self::KeyProbe>>(
self,
inner_arms: S,
) -> Result<Probe<(Self::MapClaim, S::Outputs)>, Self::Error> {
let outer_arms = self
.outer_arms
.take()
.expect("FlattenMapAccessOwned::iterate called without outer arms");
let combined = StackConcat(outer_arms, inner_arms);
let (claim, (outer_out, inner_out), extra) =
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)))
}
}
pub trait MapAccessOwned: Sized {
type Error: DeserializeError;
type MapClaim;
type KeyProbe: MapKeyProbeOwned<Error = Self::Error>;
fn fork(&mut self) -> Self;
async fn iterate<S: MapArmStackOwned<Self::KeyProbe>>(
self,
arms: S,
) -> Result<Probe<(Self::MapClaim, S::Outputs)>, Self::Error>;
}
impl<'n, C, E: DeserializeError> StrAccessOwned 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> BytesAccessOwned 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, C, E: DeserializeError> SeqAccessOwned 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::SeqClaim, R)>, Self::Error>>,
{
match self.0 {}
}
}
impl<'n, C, E: DeserializeError> SeqEntryOwned for crate::Never<'n, C, E> {
type Error = E;
type Claim = C;
fn fork(&mut self) -> Self {
match self.0 {}
}
async fn get<T: DeserializeOwned<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, C, E: DeserializeError> MapAccessOwned 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: MapArmStackOwned<Self::KeyProbe>>(
self,
_arms: S,
) -> Result<Probe<(Self::MapClaim, S::Outputs)>, Self::Error> {
match self.0 {}
}
}
impl<'n, C, E: DeserializeError> MapKeyProbeOwned 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: DeserializeOwned<Extra>, Extra>(
self,
_extra: Extra,
) -> Result<Probe<(Self::KeyClaim, K)>, Self::Error> {
match self.0 {}
}
}
impl<'n, C, E: DeserializeError> MapKeyClaimOwned 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, C, E: DeserializeError> MapValueProbeOwned 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: DeserializeOwned<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, C, E: DeserializeError> MapValueClaimOwned 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_owned_primitive {
($ty:ty, $method:ident) => {
impl DeserializeOwned for $ty {
async fn deserialize_owned<D: DeserializerOwned>(
d: D,
_extra: (),
) -> Result<Probe<(D::Claim, Self)>, D::Error> {
d.entry(|[e]| async { e.$method().await }).await
}
}
};
}
impl_deserialize_owned_primitive!(bool, deserialize_bool);
impl_deserialize_owned_primitive!(u8, deserialize_u8);
impl_deserialize_owned_primitive!(u16, deserialize_u16);
impl_deserialize_owned_primitive!(u32, deserialize_u32);
impl_deserialize_owned_primitive!(u64, deserialize_u64);
impl_deserialize_owned_primitive!(u128, deserialize_u128);
impl_deserialize_owned_primitive!(i8, deserialize_i8);
impl_deserialize_owned_primitive!(i16, deserialize_i16);
impl_deserialize_owned_primitive!(i32, deserialize_i32);
impl_deserialize_owned_primitive!(i64, deserialize_i64);
impl_deserialize_owned_primitive!(i128, deserialize_i128);
impl_deserialize_owned_primitive!(f32, deserialize_f32);
impl_deserialize_owned_primitive!(f64, deserialize_f64);
impl_deserialize_owned_primitive!(char, deserialize_char);
impl<Extra: Copy, T: DeserializeOwned<Extra>> DeserializeOwned<Extra> for Option<T> {
async fn deserialize_owned<D: DeserializerOwned>(
d: D,
extra: Extra,
) -> Result<Probe<(D::Claim, Self)>, D::Error> {
d.entry(|[e]| async { e.deserialize_option::<T, Extra>(extra).await })
.await
}
}