use std::time::{Duration, Instant};
use aranya_id::{Id, IdTag};
use tarpc::{
context,
trace::{Context as TraceContext, TraceId as TarpcTraceId},
};
const IPC_TIMEOUT: Duration = Duration::from_secs(365 * 24 * 60 * 60);
pub(crate) trait ApiId<A> {}
pub(crate) trait ApiConv<A> {
fn into_api(self) -> A;
fn from_api(val: A) -> Self;
}
impl<TTag, ATag> ApiConv<Id<ATag>> for Id<TTag>
where
TTag: IdTag,
ATag: IdTag,
Id<TTag>: ApiId<Id<ATag>>,
{
fn into_api(self) -> Id<ATag> {
Id::transmute(self)
}
fn from_api(val: Id<ATag>) -> Self {
Id::transmute(val)
}
}
macro_rules! impl_slice_iter_wrapper {
($wrapper:ident <$lifetime:lifetime> for $item:ty) => {
impl<$lifetime> Iterator for $wrapper<$lifetime> {
type Item = &$lifetime $item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
#[inline]
fn count(self) -> usize {
self.0.count()
}
#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.0.nth(n)
}
#[inline]
fn last(self) -> Option<Self::Item> {
self.0.last()
}
#[inline]
fn fold<B, F>(self, init: B, f: F) -> B
where
F: FnMut(B, Self::Item) -> B,
{
self.0.fold(init, f)
}
#[inline]
fn for_each<F>(self, f: F)
where
F: FnMut(Self::Item),
{
self.0.for_each(f)
}
#[inline]
fn all<F>(&mut self, f: F) -> bool
where
F: FnMut(Self::Item) -> bool,
{
self.0.all(f)
}
#[inline]
fn any<F>(&mut self, f: F) -> bool
where
F: FnMut(Self::Item) -> bool,
{
self.0.any(f)
}
#[inline]
fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where
P: FnMut(&Self::Item) -> bool,
{
self.0.find(predicate)
}
#[inline]
fn position<P>(&mut self, predicate: P) -> Option<usize>
where
P: FnMut(Self::Item) -> bool,
{
self.0.position(predicate)
}
#[inline]
fn rposition<P>(&mut self, predicate: P) -> Option<usize>
where
P: FnMut(Self::Item) -> bool,
{
self.0.rposition(predicate)
}
}
impl<$lifetime> DoubleEndedIterator for $wrapper<$lifetime> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back()
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.0.nth_back(n)
}
}
impl<$lifetime> ExactSizeIterator for $wrapper<$lifetime> {
#[inline]
fn len(&self) -> usize {
self.0.len()
}
}
impl<$lifetime> ::core::iter::FusedIterator for $wrapper<$lifetime> {}
};
}
pub(crate) use impl_slice_iter_wrapper;
macro_rules! impl_vec_into_iter_wrapper {
($wrapper:ident for $item:ty) => {
impl Iterator for $wrapper {
type Item = $item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
#[inline]
fn count(self) -> usize {
self.0.count()
}
#[inline]
fn last(self) -> Option<Self::Item> {
self.0.last()
}
#[inline]
fn fold<B, F>(self, init: B, f: F) -> B
where
F: FnMut(B, Self::Item) -> B,
{
self.0.fold(init, f)
}
}
impl DoubleEndedIterator for $wrapper {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back()
}
}
impl ExactSizeIterator for $wrapper {
#[inline]
fn len(&self) -> usize {
self.0.len()
}
}
impl ::core::iter::FusedIterator for $wrapper {}
};
}
pub(crate) use impl_vec_into_iter_wrapper;
pub(crate) fn rpc_context() -> context::Context {
let mut ctx = context::current();
ctx.deadline = Instant::now()
.checked_add(IPC_TIMEOUT)
.expect("IPC_TIMEOUT should not overflow");
let mut rng = rand::thread_rng();
ctx.trace_context = TraceContext {
trace_id: TarpcTraceId::random(&mut rng),
..TraceContext::default()
};
tracing::info!(rpc.trace_id = %ctx.trace_context.trace_id, "RPC: SendRequest");
ctx
}