Skip to main content

liminal_server/config/types/
open.rs

1//! `[open]`: how far an exchange with no `[auth]` reaches (ACCESS-011 R1).
2//!
3//! ACCESS-010 made an exchange with no `[auth]` open mode and bound it to
4//! loopback. This table is the operator's written choice to let that exchange
5//! listen on the network as well, for building fast on more than one machine;
6//! it changes nothing about what the exchange asks of anyone, which is still
7//! nothing. The table is refused beside `[auth]`, so it can never read as a
8//! way to loosen a gated exchange.
9
10/// The `[open]` table.
11#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Deserialize)]
12#[serde(deny_unknown_fields)]
13pub struct OpenConfig {
14    /// Where the open exchange may listen: loopback (the default without the
15    /// table) or the network.
16    #[serde(default)]
17    pub reach: Reach,
18}
19
20/// How far an open exchange or an open seat reaches.
21#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, serde::Deserialize)]
22#[serde(rename_all = "snake_case")]
23pub enum Reach {
24    /// This machine only: every listener on a loopback address.
25    #[default]
26    Loopback,
27    /// Any address the operator writes; every connection is still admitted.
28    Network,
29}
30
31impl Reach {
32    /// The word the configuration uses.
33    #[must_use]
34    pub const fn word(self) -> &'static str {
35        match self {
36            Self::Loopback => "loopback",
37            Self::Network => "network",
38        }
39    }
40}
41
42impl std::fmt::Display for Reach {
43    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44        formatter.write_str(self.word())
45    }
46}
47
48impl super::ServerConfig {
49    /// How far this exchange reaches: the `[open]` table's word, loopback
50    /// without one. Meaningful in open mode only; a gated exchange listens
51    /// where `[auth]` lets it and this answers loopback for it.
52    #[must_use]
53    pub fn open_reach(&self) -> Reach {
54        self.open.map_or(Reach::Loopback, |open| open.reach)
55    }
56}