use log::info; use roxmltree::Node; use crate::utils::xml::NodeExt; use super::{Gateway, PriorityRule}; pub(crate) fn parse_gateways(node: &Node, prefer_internal: bool) -> Option> { let node_gateways = node.find_descendant("gateways")?; let internal_gateway_list = if prefer_internal { info!("Try to parse the internal gateways..."); node_gateways.find_descendant("internal").and_then(|n| n.find_child("list")) } else { None }; let gateway_list = internal_gateway_list.or_else(|| { info!("Try to parse the external gateways..."); node_gateways.find_descendant("external").and_then(|n| n.find_child("list")) })?; let gateways = gateway_list .children() .filter_map(|gateway_item| { if !gateway_item.has_tag_name("entry") { return None; } let address = gateway_item.attribute("name").unwrap_or_default().to_string(); let name = gateway_item.child_text("description").unwrap_or_default().to_string(); let priority = gateway_item .child_text("priority") .and_then(|s| s.parse().ok()) .unwrap_or(u32::MAX); let priority_rules = gateway_item .find_child("priority-rule") .map(|n| { n.children() .filter_map(|n| { if !n.has_tag_name("entry") { return None; } let name = n.attribute("name").unwrap_or_default().to_string(); let priority: u32 = n .child_text("priority") .and_then(|s| s.parse().ok()) .unwrap_or(u32::MAX); Some(PriorityRule { name, priority }) }) .collect() }) .unwrap_or_default(); Some(Gateway { name, address, priority, priority_rules, }) }) .collect(); Some(gateways) }