Files
harmony/harmony-rs/opnsense-config-xml/src/data/interfaces.rs
2024-11-14 23:45:13 -05:00

230 lines
7.7 KiB
Rust

use xml::reader::XmlEvent;
use yaserde::{YaDeserialize as YaDeserializeTrait, YaSerialize as YaSerializeTrait};
use yaserde_derive::{YaDeserialize, YaSerialize};
use std::collections::HashMap;
use crate::xml_utils::MaybeString;
#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
pub struct Interfaces {
pub interfaces: HashMap<String, Interface>,
}
#[derive(Default, PartialEq, Debug, YaDeserialize, YaSerialize)]
pub struct Interface {
#[yaserde(rename = "if")]
pub physical_interface_name: String,
pub descr: String,
pub enable: MaybeString,
#[yaserde(rename = "spoofmac")]
pub spoof_mac: Option<MaybeString>,
pub internal_dynamic: Option<MaybeString>,
pub ipaddr: Option<MaybeString>,
#[yaserde(rename = "blockpriv")]
pub block_priv: Option<MaybeString>,
#[yaserde(rename = "blockbogons")]
pub block_bogons: Option<MaybeString>,
pub lock: Option<MaybeString>,
#[yaserde(rename = "type")]
pub r#type: Option<MaybeString>,
#[yaserde(rename = "virtual")]
pub r#virtual: Option<MaybeString>,
pub subnet: Option<MaybeString>,
pub networks: Option<MaybeString>,
pub subnetv6: Option<MaybeString>,
pub ipaddrv6: Option<MaybeString>,
#[yaserde(rename = "track6-interface")]
pub track6_interface: Option<MaybeString>,
#[yaserde(rename = "track6-prefix-id")]
pub track6_prefix_id: Option<MaybeString>,
}
pub trait MyDeserialize : YaDeserializeTrait {}
pub trait MySerialize : YaSerializeTrait {}
#[cfg(test)]
mod test {
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn should_deserialize_interfaces() {
let interfaces = yaserde::de::from_str::<Interfaces>(FULL_INTERFACES_XML).unwrap();
assert_eq!(interfaces.interfaces.len(), 6)
}
const FULL_INTERFACES_XML: &str = "<interfaces>
<wan>
<if>pppoe0</if>
<descr>WAN</descr>
<enable>1</enable>
<lock>1</lock>
<spoofmac/>
<blockpriv>1</blockpriv>
<blockbogons>1</blockbogons>
<ipaddr>pppoe</ipaddr>
</wan>
<lan>
<if>em1</if>
<descr>LAN</descr>
<enable>1</enable>
<spoofmac/>
<ipaddr>192.168.20.1</ipaddr>
<subnet>24</subnet>
<ipaddrv6>track6</ipaddrv6>
<track6-interface/>
<track6-prefix-id>0</track6-prefix-id>
</lan>
<lo0>
<internal_dynamic>1</internal_dynamic>
<descr>Loopback</descr>
<enable>1</enable>
<if>lo0</if>
<ipaddr>127.0.0.1</ipaddr>
<ipaddrv6>::1</ipaddrv6>
<subnet>8</subnet>
<subnetv6>128</subnetv6>
<type>none</type>
<virtual>1</virtual>
</lo0>
<opt1>
<if>em5</if>
<descr>backup_sync</descr>
<enable>1</enable>
<lock>1</lock>
<spoofmac/>
<ipaddr>10.10.5.1</ipaddr>
<subnet>24</subnet>
</opt1>
<wireguard>
<internal_dynamic>1</internal_dynamic>
<descr>WireGuard (Group)</descr>
<if>wireguard</if>
<virtual>1</virtual>
<enable>1</enable>
<type>group</type>
<networks/>
</wireguard>
<openvpn>
<internal_dynamic>1</internal_dynamic>
<enable>1</enable>
<if>openvpn</if>
<descr>OpenVPN</descr>
<type>group</type>
<virtual>1</virtual>
<networks/>
</openvpn>
</interfaces>";
}
// impl YaSerializeTrait for Interfaces {
// fn serialize<W: std::io::Write>(
// &self,
// writer: &mut yaserde::ser::Serializer<W>,
// ) -> Result<(), String> {
// writer.write("Interfaces serializer TODO").map_err(|e| e.to_string())
// }
//
// fn serialize_attributes(
// &self,
// attributes: Vec<xml::attribute::OwnedAttribute>,
// namespace: xml::namespace::Namespace,
// ) -> Result<
// (
// Vec<xml::attribute::OwnedAttribute>,
// xml::namespace::Namespace,
// ),
// String,
// > {
// todo!()
// }
// }
//
// impl YaDeserializeTrait for Interfaces {
// fn deserialize<R: std::io::Read>(
// reader: &mut yaserde::de::Deserializer<R>,
// ) -> Result<Self, String> {
// let mut interfaces = Interfaces::default();
// let mut current_interface_name = String::new();
// let mut current_interface = Interface::default();
//
// let mut event = reader.next_event()?;
// loop {
// match event {
// xml::reader::XmlEvent::EndElement { name } => {
// println!(
// "Handling EndElement {}, current_interface_name: {}",
// name.local_name, current_interface_name
// );
// println!("Peeking after EndElement {:?}", reader.peek()?);
// if name.local_name == "interfaces" {
// break;
// }
// todo!("Should not hit here");
// }
// xml::reader::XmlEvent::StartElement { ref name, .. } => {
// println!("Got start Element {:?}", name);
// current_interface_name = name.local_name.clone();
// println!("About to deserialize interface from name {:?}", name);
// // TODO store names
// 'inner_iface: loop {
// let peek = reader.peek()?;
// println!("Peeking before forcing next event {:?}", peek);
//
// if let XmlEvent::EndElement { name } = peek {
// // TODO save the interface name and struct in the hashmap
// println!("Forcing next_event");
// reader.next_event()?;
//
// let peek = reader.peek()?;
// println!("Peeking after next event deserializing {:?}", peek);
// if let XmlEvent::EndElement { name } = peek {
// println!("Got two EndElement in a row, breaking out of loop");
// break 'inner_iface;
// }
// }
// println!("Peeking before deserializing {:?}", reader.peek()?);
// let interface = <Interface as yaserde::YaDeserialize>::deserialize(reader)?;
// println!("Interface deserialized {:?}", interface);
// println!("Peeking after deserializing {:?}", reader.peek()?);
// }
// println!(
// "Done with inner interface, loop completed {:?}",
// reader.peek()?
// );
// }
// xml::reader::XmlEvent::EndDocument => break,
// _ => {
// return Err(
// "This Interfaces Deserializer does not support all XmlEvent types".into(),
// )
// }
// }
// let peek = reader.peek()?;
//
// let read_next = true;
// if let XmlEvent::EndElement { name } = peek {
// if name.local_name == "interfaces" {
// println!("Got endElement interfaces, not reading next event");
// break;
// }
// }
//
// if read_next {
// event = reader.next_event()?;
// }
// println!("Outer loop got event {:?}", event);
// println!("Outer loop got peek {:?}", reader.peek()?);
// }
// println!("Done with interfaces {:?}", interfaces);
// println!("reader peeking shows {:?}", reader.peek());
//
// Ok(interfaces)
// }
// }