use std::pin::Pin; use anyhow::{anyhow, Result}; use futures::future::{try_join_all, Future}; // use tokio::try_join; type ActorTask = Pin>>>; use crate::{ config::ConfigOpts, consul_actor::ConsulActor, fw_actor::FirewallActor, igd_actor::IgdActor, }; pub struct Diplonat { actors: Vec, } impl Diplonat { pub async fn new() -> Result { let config = ConfigOpts::from_env()?; println!("{:#?}", config); let mut consul_actor = ConsulActor::new(config.consul); let consul_rx = consul_actor.rx_open_ports.clone(); let actor_task: ActorTask = Box::pin(consul_actor.listen()); let mut actors = vec![actor_task]; if let Some(mut actor) = FirewallActor::new(config.firewall, &consul_rx)? { let actor_task: ActorTask = Box::pin(actor.listen()); actors.push(actor_task); } if let Some(mut actor) = IgdActor::new(config.igd, &consul_rx).await? { let actor_task: ActorTask = Box::pin(actor.listen()); actors.push(actor_task); } if actors.len() == 1 { return Err(anyhow!( "At least enable *one* module, otherwise it's boring!" )) } Ok(Self { actors }) } pub async fn listen(&self) -> Result<()> { try_join_all(self.actors); Ok(()) } }