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
use crate::FirewallError;
use std::fmt::{Display, Formatter};
use std::str::FromStr;

/// Action dictated by a firewall rule.
///
/// Each firewall rule is associated to a given action.
#[derive(Default, Copy, Clone, Eq, PartialEq, Debug)]
pub enum FirewallAction {
    /// Allows traffic that matches the rule to pass.
    #[default]
    ACCEPT,
    /// Silently blocks traffic that matches the rule.
    DENY,
    /// Blocks traffic that matches the rule.
    ///
    /// An *ICMP Destination Unreachable* message should be sent back to the traffic source.
    REJECT,
}

impl Display for FirewallAction {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let str = match self {
            FirewallAction::ACCEPT => "ACCEPT",
            FirewallAction::DENY => "DENY",
            FirewallAction::REJECT => "REJECT",
        };

        write!(f, "{str}")
    }
}

impl FromStr for FirewallAction {
    type Err = FirewallError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "ACCEPT" => Ok(Self::ACCEPT),
            "DENY" => Ok(Self::DENY),
            "REJECT" => Ok(Self::REJECT),
            x => Err(FirewallError::InvalidAction(x.to_owned())),
        }
    }
}