1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
use std::{cell::RefCell, io, rc::Rc, vec::IntoIter}; use uptown_funk::{Executor, FromWasm, ToWasm}; use super::api::TcpState; #[derive(Clone)] pub struct Resolver { iter: Rc<RefCell<IntoIter<smol::net::SocketAddr>>>, } impl Resolver { pub async fn resolve(name: &str) -> Result<Self, io::Error> { let resolved = smol::net::resolve(name).await?; Ok(Resolver { iter: Rc::new(RefCell::new(resolved.into_iter())), }) } pub fn next(&self) -> Option<smol::net::SocketAddr> { self.iter.as_ref().borrow_mut().next() } } impl FromWasm for Resolver { type From = u32; type State = TcpState; fn from( state: &mut Self::State, _: &impl Executor, resolver_id: u32, ) -> Result<Self, uptown_funk::Trap> where Self: Sized, { match state.resolvers.get(resolver_id) { Some(resolver) => Ok(resolver.clone()), None => Err(uptown_funk::Trap::new("TcpListener not found")), } } } pub enum ResolverResult { Ok(Resolver), Err(String), } impl ToWasm for ResolverResult { type To = u32; type State = TcpState; fn to( state: &mut Self::State, _: &impl Executor, result: Self, ) -> Result<u32, uptown_funk::Trap> { match result { ResolverResult::Ok(resolver) => Ok(state.resolvers.add(resolver)), ResolverResult::Err(_err) => Ok(0), } } }