nullnet-libfireparse 0.3.4

A library for parsing and translating firewall configurations across multiple NullNet targets
Documentation
use roxmltree::Node;

const ANY_ADDR_VALUE: &str = "*";
const ANY_PORT_VALUE: &str = "*";
const DEFAULT_TYPE_VALUE: &str = "address";
const DEFAULT_INVERSED: bool = false;

pub struct EndpointParser {}

impl EndpointParser {
    pub fn parse(node: Option<Node>) -> (String, String, String, bool) {
        if node.is_none() {
            return (
                String::from(ANY_ADDR_VALUE),
                String::from(ANY_PORT_VALUE),
                String::from(DEFAULT_TYPE_VALUE),
                DEFAULT_INVERSED,
            );
        }

        let node_value = node.unwrap();

        let addr = Self::parse_addr(&node_value);
        let port = Self::parse_port(&node_value);
        let r#type = Self::parse_addr_type(&node_value);
        let inversed = Self::parse_inversed(&node_value);

        (addr, port, r#type, inversed)
    }

    fn parse_port(node: &Node) -> String {
        node.children()
            .find(|e| e.has_tag_name("port"))
            .and_then(|e| e.text())
            .unwrap_or(ANY_PORT_VALUE)
            .to_string()
    }

    fn parse_addr(node: &Node) -> String {
        if node.children().any(|e| e.has_tag_name("any")) {
            return String::from(ANY_ADDR_VALUE);
        }

        if let Some(address) = node
            .children()
            .find(|e| e.has_tag_name("address"))
            .and_then(|e| e.text())
        {
            return String::from(address);
        }

        if let Some(network) = node
            .children()
            .find(|e| e.has_tag_name("network"))
            .and_then(|e| e.text())
        {
            return String::from(network);
        }

        String::from(ANY_ADDR_VALUE)
    }

    fn parse_addr_type(node: &Node) -> String {
        match node.children().any(|e| e.has_tag_name("network")) {
            true => String::from("network"),
            false => String::from("address"),
        }
    }

    fn parse_inversed(node: &Node) -> bool {
        node.children().any(|e| e.has_tag_name("not"))
    }
}