mum_cli/
network.rs

1pub mod tcp;
2pub mod udp;
3
4use futures_util::FutureExt;
5use log::*;
6use std::{future::Future, net::SocketAddr};
7use tokio::{
8    select,
9    sync::{oneshot, watch},
10};
11
12use crate::state::StatePhase;
13
14#[derive(Clone, Debug)]
15pub struct ConnectionInfo {
16    socket_addr: SocketAddr,
17    hostname: String,
18    accept_invalid_cert: bool,
19}
20
21impl ConnectionInfo {
22    pub fn new(socket_addr: SocketAddr, hostname: String, accept_invalid_cert: bool) -> Self {
23        Self {
24            socket_addr,
25            hostname,
26            accept_invalid_cert,
27        }
28    }
29}
30
31#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
32pub enum VoiceStreamType {
33    Tcp,
34    Udp,
35}
36
37async fn run_until<F, R>(
38    phase_checker: impl Fn(StatePhase) -> bool,
39    fut: F,
40    mut phase_watcher: watch::Receiver<StatePhase>,
41) -> Option<R>
42where
43    F: Future<Output = R>,
44{
45    let (tx, rx) = oneshot::channel();
46    let phase_transition_block = async {
47        loop {
48            phase_watcher.changed().await.unwrap();
49            if phase_checker(*phase_watcher.borrow()) {
50                break;
51            }
52        }
53        if tx.send(true).is_err() {
54            warn!("future resolved before it could be cancelled");
55        }
56    };
57
58    let main_block = async {
59        let rx = rx.fuse();
60        let fut = fut.fuse();
61        select! {
62            r = fut => Some(r),
63            _ = rx => None,
64        }
65    };
66
67    select! {
68        m = main_block => m,
69        _ = phase_transition_block => None,
70    }
71}