use miette::{miette, IntoDiagnostic};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
pub struct NodeCallback {
tcp_listener: tokio::net::TcpListener,
callback_port: u16,
}
impl NodeCallback {
pub async fn create() -> miette::Result<Self> {
let tcp_listener =
tokio::net::TcpListener::bind(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 0))
.await
.map_err(|_| miette!("Failed to bind callback listener"))?;
let callback_port = tcp_listener
.local_addr()
.map_err(|_| miette!("Failed to get callback listener port"))?
.port();
Ok(Self {
tcp_listener,
callback_port,
})
}
pub async fn wait_for_signal(self) -> miette::Result<()> {
_ = self
.tcp_listener
.accept()
.await
.map_err(|_| miette!("Failed to accept node callback connection"))?;
Ok(())
}
pub async fn signal(callback_port: u16) -> miette::Result<()> {
tokio::net::TcpStream::connect(SocketAddr::new(
IpAddr::V4(Ipv4Addr::LOCALHOST),
callback_port,
))
.await
.into_diagnostic()?;
Ok(())
}
pub fn callback_port(&self) -> u16 {
self.callback_port
}
}