use std::pin::Pin; use anyhow::{anyhow, Result}; use futures::future::{try_join_all, Future}; use tokio::try_join; 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 consul_actor = ConsulActor::new(config.consul); let mut actors = vec![Box::pin(consul_actor.listen())]; if let Some(actor) = FirewallActor::new(config.firewall, &consul_actor.rx_open_ports)? { actors.push(Box::pin(actor.listen())); } if let Some(actor) = IgdActor::new(config.igd, &consul_actor.rx_open_ports).await? { actors.push(Box::pin(actor.listen())); } 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(()) } }