asimov_protocol/
resolve_handle.rs1use crate::PeerId;
4use alloc::boxed::Box;
5use asimov_id::{Handle, Id};
6use core::pin::Pin;
7use futures_lite::{Stream, StreamExt, stream};
8
9pub trait ResolveHandle {
11 type Error: core::fmt::Debug + Send;
12
13 fn resolve_random(
18 &mut self,
19 id: impl Into<Id>,
20 ) -> impl Future<Output = Result<Option<PeerId>, Self::Error>> {
21 #[cfg(not(feature = "random"))]
22 {
23 unimplemented!("resolve_random requires the `random` feature");
24 return async { Ok(None) };
25 }
26
27 #[cfg(feature = "random")]
28 async move {
29 let mut stream = Box::pin(self.resolve_all(id));
30 let mut results = alloc::vec::Vec::new();
31 while let Some(result) = stream.next().await {
32 let Ok(result) = result else {
33 continue; };
35 results.push(result);
36 }
37 let index = fastrand::usize(..results.len());
38 Ok(results.get(index).copied())
39 }
40 }
41
42 fn resolve_first(
45 &mut self,
46 id: impl Into<Id>,
47 ) -> impl Future<Output = Result<Option<PeerId>, Self::Error>> {
48 async move {
49 let mut stream = Box::pin(self.resolve_all(id));
50 while let Some(result) = stream.next().await {
51 let Ok(result) = result else {
52 continue; };
54 return Ok(Some(result));
55 }
56 Ok(None)
57 }
58 }
59
60 fn resolve_all(
62 &mut self,
63 id: impl Into<Id>,
64 ) -> impl Stream<Item = Result<PeerId, Self::Error>> + Send {
65 let output: Pin<Box<dyn Stream<Item = Result<PeerId, Self::Error>> + Send>> =
66 match id.into() {
67 Id::Handle(handle) => Box::pin(self.resolve_handle(handle)),
68 Id::PublicKey(key) => Box::pin(stream::once(Ok(key))),
69 };
70 output
71 }
72
73 fn resolve_handle(
77 &mut self,
78 _handle: impl Into<Handle>,
79 ) -> impl Stream<Item = Result<PeerId, Self::Error>> + Send {
80 Box::pin(stream::empty())
81 }
82}