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
// SPDX-License-Identifier: AGPL-3.0-or-later
//! Common types that are used in multiple modules.

use std::{
    fmt::Display,
    net::{IpAddr, SocketAddr},
    sync::Arc,
};

use btlib::BlockPath;
use btserde::field_helpers::smart_ptr;
use serde::{Deserialize, Serialize};

use crate::Result;

/// Trait for messages which can be transmitted using the call method.
pub trait CallMsg<'de>: Serialize + Deserialize<'de> + Send + Sync {
    type Reply<'r>: Serialize + Deserialize<'r> + Send;
}

/// Trait for messages which can be transmitted using the send method.
/// Types which implement this trait should specify `()` as their reply type.
pub trait SendMsg<'de>: CallMsg<'de> {}

/// An address which identifies a block on the network. An instance of this struct can be
/// used to get a socket address for the block this address refers to.
#[derive(PartialEq, Eq, Hash, Clone, Debug, Serialize, Deserialize)]
pub struct BlockAddr {
    #[serde(rename = "ipaddr")]
    ip_addr: IpAddr,
    #[serde(with = "smart_ptr")]
    path: Arc<BlockPath>,
}

impl BlockAddr {
    pub fn new(ip_addr: IpAddr, path: Arc<BlockPath>) -> Self {
        Self { ip_addr, path }
    }

    pub fn ip_addr(&self) -> IpAddr {
        self.ip_addr
    }

    pub fn path(&self) -> &Arc<BlockPath> {
        &self.path
    }

    fn port(&self) -> Result<u16> {
        self.path.port()
    }

    /// Returns the socket address of the block this instance refers to.
    pub fn socket_addr(&self) -> Result<SocketAddr> {
        Ok(SocketAddr::new(self.ip_addr, self.port()?))
    }
}

impl Display for BlockAddr {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}@{}", self.path, self.ip_addr)
    }
}