ReSet_Lib/network/
connection.rs

1use std::{collections::HashMap, str::FromStr};
2
3use dbus::arg::{self, prop_cast, PropMap, RefArg, Variant};
4
5
6pub trait PropMapConvert: Sized {
7    fn from_propmap(map: PropMap) -> Self;
8    fn to_propmap(&self, map: &mut PropMap);
9}
10
11pub trait Enum: Sized {
12    fn from_i32(num: i32) -> Self;
13    fn to_i32(&self) -> i32;
14}
15
16#[derive(Debug)]
17#[allow(dead_code)]
18pub struct ConversionError {
19    message: &'static str,
20}
21
22#[derive(Debug, Default)]
23pub struct Connection {
24    pub settings: ConnectionSettings,
25    // x802: X802Settings,
26    pub device: TypeSettings,
27    pub ipv4: IPV4Settings,
28    pub ipv6: IPV6Settings,
29    // TODO check if x802 is actually even necessary?
30    // TODO implement wifi security settings
31}
32
33impl Connection {
34    pub fn convert_from_propmap(
35        map: HashMap<
36            std::string::String,
37            HashMap<std::string::String, dbus::arg::Variant<Box<dyn RefArg>>>,
38        >,
39    ) -> Result<Self, ConversionError> {
40        let mut settings: Option<ConnectionSettings> = None;
41        // let mut x802: Option<X802Settings> = None;
42        let mut device: Option<TypeSettings> = None;
43        let mut ipv4: Option<IPV4Settings> = None;
44        let mut ipv6: Option<IPV6Settings> = None;
45        for (category, submap) in map {
46            match category.as_str() {
47                "802-11-wireless" => {
48                    device = Some(TypeSettings::WIFI(WifiSettings::from_propmap(submap)))
49                }
50                "802-3-ethernet" => {
51                    device = Some(TypeSettings::ETHERNET(EthernetSettings::from_propmap(
52                        submap,
53                    )))
54                }
55                "vpn" => device = Some(TypeSettings::VPN(VPNSettings::from_propmap(submap))),
56                "ipv6" => ipv6 = Some(IPV6Settings::from_propmap(submap)),
57                "ipv4" => ipv4 = Some(IPV4Settings::from_propmap(submap)),
58                "connection" => settings = Some(ConnectionSettings::from_propmap(submap)),
59                // "802-1x" => x802 = Some(X802Settings::from_propmap(submap)),
60                _ => continue,
61            }
62        }
63        if settings.is_none() | device.is_none() | ipv4.is_none() | ipv6.is_none() {
64            return Err(ConversionError {
65                message: "could not convert propmap",
66            });
67        }
68        let settings = settings.unwrap();
69        // let x802 = x802.unwrap();
70        let device = device.unwrap();
71        let ipv4 = ipv4.unwrap();
72        let ipv6 = ipv6.unwrap();
73        Ok(Self {
74            settings,
75            // x802,
76            device,
77            ipv4,
78            ipv6,
79        })
80    }
81
82    pub fn convert_to_propmap(&self) -> PropMap {
83        let mut map = PropMap::new();
84        self.settings.to_propmap(&mut map);
85        match &self.device {
86            TypeSettings::WIFI(wifi) => wifi.to_propmap(&mut map),
87            TypeSettings::ETHERNET(ethernet) => ethernet.to_propmap(&mut map),
88            TypeSettings::VPN(vpn) => vpn.to_propmap(&mut map),
89            TypeSettings::None => (),
90        }
91        self.ipv4.to_propmap(&mut map);
92        self.ipv6.to_propmap(&mut map);
93        map
94    }
95}
96
97#[derive(Clone, Copy, Default, Debug)]
98pub enum Trust {
99    HOME,
100    WORK,
101    PUBLIC,
102    #[default]
103    DEFAULT,
104}
105
106impl FromStr for Trust {
107    type Err = ConversionError;
108
109    fn from_str(s: &str) -> Result<Self, Self::Err> {
110        match s {
111            "Home" => Ok(Trust::HOME),
112            "Work" => Ok(Trust::WORK),
113            "Public" => Ok(Trust::PUBLIC),
114            _ => Ok(Trust::DEFAULT),
115        }
116    }
117}
118
119impl ToString for Trust {
120    fn to_string(&self) -> String {
121        match self {
122            Trust::HOME => String::from("Home"),
123            Trust::WORK => String::from("Work"),
124            Trust::PUBLIC => String::from("Public"),
125            Trust::DEFAULT => String::from("null"),
126        }
127    }
128}
129
130impl Enum for Trust {
131    fn from_i32(num: i32) -> Self {
132        match num {
133            0 => Trust::HOME,
134            1 => Trust::WORK,
135            2 => Trust::PUBLIC,
136            _ => Trust::DEFAULT,
137        }
138    }
139
140    fn to_i32(&self) -> i32 {
141        match self {
142            Trust::HOME => 0,
143            Trust::WORK => 1,
144            Trust::PUBLIC => 2,
145            Trust::DEFAULT => 3,
146        }
147    }
148}
149
150#[derive(Default, Debug, Clone)]
151pub enum Mode {
152    #[default]
153    INFRASTRUCTURE,
154    ADHOC,
155    AP,
156}
157
158impl FromStr for Mode {
159    type Err = ConversionError;
160
161    fn from_str(s: &str) -> Result<Self, Self::Err> {
162        match s {
163            "adhoc" => Ok(Mode::ADHOC),
164            "ap" => Ok(Mode::AP),
165            _ => Ok(Mode::INFRASTRUCTURE),
166        }
167    }
168}
169
170impl ToString for Mode {
171    fn to_string(&self) -> String {
172        match self {
173            Mode::ADHOC => String::from("adhoc"),
174            Mode::AP => String::from("ap"),
175            Mode::INFRASTRUCTURE => String::from("infrastructure"),
176        }
177    }
178}
179
180impl Enum for Mode {
181    fn from_i32(num: i32) -> Self {
182        match num {
183            0 => Mode::INFRASTRUCTURE,
184            1 => Mode::ADHOC,
185            _ => Mode::AP,
186        }
187    }
188
189    fn to_i32(&self) -> i32 {
190        match self {
191            Mode::INFRASTRUCTURE => 0,
192            Mode::ADHOC => 1,
193            Mode::AP => 2,
194        }
195    }
196}
197
198#[derive(Default, Debug, Clone)]
199pub enum Band {
200    _5GHZ,
201    _24GHZ,
202    #[default]
203    DYN,
204}
205
206impl FromStr for Band {
207    type Err = ConversionError;
208
209    fn from_str(s: &str) -> Result<Self, Self::Err> {
210        match s {
211            "a" => Ok(Band::_5GHZ),
212            "bg" => Ok(Band::_24GHZ),
213            _ => Ok(Band::DYN),
214        }
215    }
216}
217
218impl ToString for Band {
219    fn to_string(&self) -> String {
220        match self {
221            Band::_5GHZ => String::from("bg"),
222            Band::_24GHZ => String::from("a"),
223            Band::DYN => String::from(""),
224        }
225    }
226}
227
228impl Enum for Band {
229    fn from_i32(num: i32) -> Self {
230        match num {
231            0 => Band::_5GHZ,
232            1 => Band::_24GHZ,
233            _ => Band::DYN,
234        }
235    }
236
237    fn to_i32(&self) -> i32 {
238        match self {
239            Band::_5GHZ => 0,
240            Band::_24GHZ => 1,
241            Band::DYN => 2,
242        }
243    }
244}
245
246#[derive(Default, Debug, Clone)]
247pub enum Duplex {
248    HALF,
249    #[default]
250    FULL,
251}
252
253impl FromStr for Duplex {
254    type Err = ConversionError;
255
256    fn from_str(s: &str) -> Result<Self, Self::Err> {
257        match s {
258            "half" => Ok(Duplex::HALF),
259            _ => Ok(Duplex::FULL),
260        }
261    }
262}
263
264impl ToString for Duplex {
265    fn to_string(&self) -> String {
266        match self {
267            Duplex::HALF => String::from("half"),
268            Duplex::FULL => String::from("full"),
269        }
270    }
271}
272
273impl Enum for Duplex {
274    fn from_i32(num: i32) -> Self {
275        match num {
276            0 => Duplex::HALF,
277            _ => Duplex::FULL,
278        }
279    }
280
281    fn to_i32(&self) -> i32 {
282        match self {
283            Duplex::HALF => 0,
284            Duplex::FULL => 1,
285        }
286    }
287}
288
289#[derive(Debug, Default)]
290pub enum TypeSettings {
291    WIFI(WifiSettings),
292    ETHERNET(EthernetSettings),
293    VPN(VPNSettings),
294    #[default]
295    None,
296}
297
298impl ToString for TypeSettings {
299    fn to_string(&self) -> String {
300        match self {
301            TypeSettings::WIFI(_) => String::from("wifi"),
302            TypeSettings::ETHERNET(_) => String::from("ethernet"),
303            TypeSettings::VPN(_) => String::from("vpn"),
304            TypeSettings::None => String::from(""),
305        }
306    }
307}
308
309#[derive(Debug, Clone, Default)]
310pub struct EthernetSettings {
311    pub auto_negotiate: bool,
312    pub cloned_mac_address: String,
313    pub duplex: Duplex,
314    pub mtu: u32,
315    pub name: String,
316    pub speed: u32,
317}
318
319impl PropMapConvert for EthernetSettings {
320    fn from_propmap(map: PropMap) -> Self {
321        let auto_negotiate: Option<&bool> = prop_cast(&map, "auto-negotiate");
322        let cloned_mac_address: String;
323        let cloned_address_opt: Option<&String> = prop_cast(&map, "cloned-mac-address");
324        if cloned_address_opt.is_none() {
325            cloned_mac_address = String::from("");
326        } else {
327            cloned_mac_address = cloned_address_opt.unwrap().clone();
328        }
329        let duplex: Duplex;
330        let duplex_opt: Option<&String> = prop_cast(&map, "mode");
331        if duplex_opt.is_none() {
332            duplex = Duplex::FULL;
333        } else {
334            duplex = Duplex::from_str(duplex_opt.unwrap().as_str()).ok().unwrap();
335        }
336        let mtu: Option<&u32> = prop_cast(&map, "mtu");
337        let name: String;
338        let name_opt: Option<&String> = prop_cast(&map, "name");
339        if name_opt.is_none() {
340            name = String::from("");
341        } else {
342            name = name_opt.unwrap().clone();
343        }
344        let speed: Option<&u32> = prop_cast(&map, "speed");
345        Self {
346            auto_negotiate: *auto_negotiate.unwrap_or(&true),
347            cloned_mac_address,
348            duplex,
349            mtu: *mtu.unwrap_or(&0),
350            name,
351            speed: *speed.unwrap_or(&0),
352        }
353    }
354
355    fn to_propmap(&self, map: &mut PropMap) {
356        map.insert(
357            "auto-negotiate".into(),
358            Variant(Box::new(self.auto_negotiate)),
359        );
360        map.insert("duplex".into(), Variant(Box::new(self.duplex.to_i32())));
361        map.insert("mtu".into(), Variant(Box::new(self.mtu)));
362        map.insert("name".into(), Variant(Box::new(self.name.clone())));
363        map.insert("speed".into(), Variant(Box::new(self.speed)));
364    }
365}
366
367#[derive(Debug, Clone)]
368pub struct VPNSettings {
369    pub data: HashMap<String, String>,
370    pub name: String,
371    pub persistent: bool,
372    pub secrets: HashMap<String, String>,
373    pub service_type: String,
374    pub timeout: u32,
375    pub user_name: String,
376}
377
378impl PropMapConvert for VPNSettings {
379    fn from_propmap(map: PropMap) -> Self {
380        let data: HashMap<String, String>;
381        let name: String;
382        let secrets: HashMap<String, String>;
383        let service_type: String;
384        let user_name: String;
385
386        let data_opt: Option<&HashMap<String, String>> = prop_cast(&map, "data");
387        if data_opt.is_none() {
388            data = HashMap::new();
389        } else {
390            data = data_opt.unwrap().clone();
391        }
392        let name_opt: Option<&String> = prop_cast(&map, "name");
393        if name_opt.is_none() {
394            name = String::from("vpn");
395        } else {
396            name = name_opt.unwrap().clone();
397        }
398        let persistent: Option<&bool> = prop_cast(&map, "persistent");
399        let secrets_opt: Option<&HashMap<String, String>> = prop_cast(&map, "secrets");
400        if secrets_opt.is_none() {
401            secrets = HashMap::new();
402        } else {
403            secrets = secrets_opt.unwrap().clone();
404        }
405        let service_type_opt: Option<&String> = prop_cast(&map, "service-type");
406        if service_type_opt.is_none() {
407            service_type = String::from("");
408        } else {
409            service_type = service_type_opt.unwrap().clone();
410        }
411        let timeout: Option<&u32> = prop_cast(&map, "timeout");
412        let user_name_opt: Option<&String> = prop_cast(&map, "user-name");
413        if user_name_opt.is_none() {
414            user_name = String::from("");
415        } else {
416            user_name = user_name_opt.unwrap().clone();
417        }
418        Self {
419            data,
420            name,
421            persistent: *persistent.unwrap_or(&false),
422            secrets,
423            service_type,
424            timeout: *timeout.unwrap_or(&0),
425            user_name,
426        }
427    }
428
429    fn to_propmap(&self, map: &mut PropMap) {
430        map.insert("data".into(), Variant(Box::new(self.data.clone())));
431        map.insert("name".into(), Variant(Box::new(self.name.clone())));
432        map.insert("persistent".into(), Variant(Box::new(self.persistent)));
433        map.insert("secrets".into(), Variant(Box::new(self.secrets.clone())));
434        map.insert(
435            "service-type".into(),
436            Variant(Box::new(self.service_type.clone())),
437        );
438        map.insert("timeout".into(), Variant(Box::new(self.timeout)));
439        map.insert(
440            "user-name".into(),
441            Variant(Box::new(self.user_name.clone())),
442        );
443    }
444}
445
446#[derive(Debug, Clone)]
447pub struct WifiSettings {
448    pub band: Band,
449    pub channel: u32,
450    pub cloned_mac_address: String,
451    pub mode: Mode,
452    pub mtu: u32,
453    pub powersave: u32,
454    pub rate: u32,
455    pub ssid: Vec<u8>,
456    pub security_settings: WifiSecuritySettings,
457}
458
459impl PropMapConvert for WifiSettings {
460    fn from_propmap(map: PropMap) -> Self {
461        println!("wifi debug");
462        for (key, val) in map.iter() {
463            dbg!(key);
464            dbg!(val);
465        }
466        let mode: Mode;
467        let band: Band;
468        let mode_opt: Option<&String> = prop_cast(&map, "mode");
469        if mode_opt.is_none() {
470            mode = Mode::from_str("").ok().unwrap();
471        } else {
472            mode = Mode::from_str(mode_opt.unwrap().as_str()).ok().unwrap();
473        }
474        let channel_opt: Option<&u32> = prop_cast(&map, "channel");
475        let channel = *channel_opt.unwrap_or(&0);
476        let band_opt: Option<&String> = prop_cast(&map, "band");
477        if band_opt.is_none() {
478            band = Band::from_str("").ok().unwrap();
479        } else {
480            band = Band::from_str(band_opt.unwrap().as_str()).ok().unwrap();
481        }
482        let cloned_mac_address: String;
483        let cloned_address_opt: Option<&String> = prop_cast(&map, "cloned-mac-address");
484        if cloned_address_opt.is_none() {
485            cloned_mac_address = String::from("");
486        } else {
487            cloned_mac_address = cloned_address_opt.unwrap().clone();
488        }
489        let mtu_opt: Option<&u32> = prop_cast(&map, "mtu");
490        let mtu = *mtu_opt.unwrap_or(&0);
491        let powersave_opt: Option<&u32> = prop_cast(&map, "powersave");
492        let powersave = *powersave_opt.unwrap_or(&0);
493        let rate_opt: Option<&u32> = prop_cast(&map, "rate");
494        let rate = *rate_opt.unwrap_or(&0);
495        let ssid: Vec<u8>;
496        let ssid_opt: Option<&Vec<u8>> = prop_cast(&map, "ssid");
497        if ssid_opt.is_none() {
498            ssid = Vec::new();
499        } else {
500            ssid = ssid_opt.unwrap().clone();
501        }
502        let security_settings = WifiSecuritySettings::from_propmap(map);
503        Self {
504            band,
505            channel,
506            cloned_mac_address,
507            mode,
508            mtu,
509            powersave,
510            rate,
511            ssid,
512            security_settings,
513        }
514    }
515
516    fn to_propmap(&self, map: &mut PropMap) {
517        map.insert("band".into(), Variant(Box::new(self.band.to_i32())));
518        map.insert("channel".into(), Variant(Box::new(self.channel)));
519        map.insert("mode".into(), Variant(Box::new(self.mode.to_i32())));
520        map.insert("mtu".into(), Variant(Box::new(self.mtu)));
521        map.insert("powersave".into(), Variant(Box::new(self.powersave)));
522        map.insert("rate".into(), Variant(Box::new(self.rate)));
523        map.insert("ssid".into(), Variant(Box::new(self.ssid.clone())));
524        self.security_settings.to_propmap(map);
525    }
526}
527
528#[derive(Debug)]
529#[allow(dead_code)]
530pub struct X802Settings {
531    pub ca_cert: Vec<u8>,
532    pub ca_cert_string: String,
533    pub client_cert: Vec<u8>,
534    pub domain_suffix: String,
535    pub eap: Vec<String>,
536    pub identity: String,
537    pub pac_file: String,
538    pub password: String,
539    pub password_flags: u32,
540    pub password_raw_flags: Vec<u8>,
541}
542
543// impl PropMapConvert for X802Settings {
544//     fn from_propmap(map: PropMap) -> Self {
545//         println!("x802 debug");
546//         for (key, val) in map.iter() {
547//             dbg!(key);
548//             dbg!(val);
549//         }
550//         let ca_cert: Vec<u8>;
551//         let ca_cert_string: String;
552//         let client_cert: Vec<u8>;
553//         let domain_suffix: String;
554//         let eap: Vec<String>;
555//         let identity: String;
556//         let pac_file: String;
557//         let password: String;
558//         let password_raw_flags: Vec<u8>;
559//         let password_flags = prop_cast(&map, "password-flags");
560//         let ca_cert_opt: Option<&Vec<u8>> = prop_cast(&map, "ca-cert");
561//         if ca_cert_opt.is_none() {
562//             ca_cert = Vec::new();
563//         } else {
564//             ca_cert = ca_cert_opt.unwrap().clone();
565//         }
566//         let ca_cert_string_opt: Option<&String> = prop_cast(&map, "ca-cert-string");
567//         if ca_cert_string_opt.is_none() {
568//             ca_cert_string = String::new();
569//         } else {
570//             ca_cert_string = ca_cert_string_opt.unwrap().clone();
571//         }
572//         let client_cert_opt: Option<&Vec<u8>> = prop_cast(&map, "client-cert");
573//         if client_cert_opt.is_none() {
574//             client_cert = Vec::new();
575//         } else {
576//             client_cert = client_cert_opt.unwrap().clone();
577//         }
578//         let domain_suffix_opt: Option<&String> = prop_cast(&map, "domain-suffix");
579//         if domain_suffix_opt.is_none() {
580//             domain_suffix = String::from("");
581//         } else {
582//             domain_suffix = domain_suffix_opt.unwrap().clone();
583//         }
584//         let eap_opt: Option<&Vec<String>> = prop_cast(&map, "eap");
585//         if eap_opt.is_none() {
586//             eap = Vec::new();
587//         } else {
588//             eap = eap_opt.unwrap().clone();
589//         }
590//         let identity_opt: Option<&String> = prop_cast(&map, "identity");
591//         if identity_opt.is_none() {
592//             identity = String::from("");
593//         } else {
594//             identity = identity_opt.unwrap().clone();
595//         }
596//         let pac_file_opt: Option<&String> = prop_cast(&map, "pac-file");
597//         if pac_file_opt.is_none() {
598//             pac_file = String::from("");
599//         } else {
600//             pac_file = pac_file_opt.unwrap().clone();
601//         }
602//         let password_opt: Option<&String> = prop_cast(&map, "password");
603//         if password_opt.is_none() {
604//             password = String::from("");
605//         } else {
606//             password = password_opt.unwrap().clone();
607//         }
608//         let password_raw_flags_opt: Option<&Vec<u8>> = prop_cast(&map, "password-raw-flags");
609//         if password_raw_flags_opt.is_none() {
610//             password_raw_flags = Vec::new();
611//         } else {
612//             password_raw_flags = password_raw_flags_opt.unwrap().clone();
613//         }
614//         Self {
615//             ca_cert,
616//             ca_cert_string,
617//             client_cert,
618//             domain_suffix,
619//             eap,
620//             identity,
621//             pac_file,
622//             password,
623//             password_flags: *password_flags.unwrap_or_else(|| &0),
624//             password_raw_flags,
625//         }
626//     }
627// }
628
629#[derive(Debug, Default)]
630pub struct Address {
631    pub address: String,
632    pub prefix_length: u32,
633    pub gateway: Option<String>,
634    pub metric: Option<u32>,
635}
636
637impl Address {
638    pub fn new(address: String, prefix_length: u32, gateway: Option<String>, metric: Option<u32>) -> Self {
639        Address { address, prefix_length, gateway, metric }
640    }
641
642    pub fn theBetterNew(address: String, prefix_length: u32) -> Self {
643        Address { address, prefix_length, gateway: None, metric: None }
644    }
645
646    pub fn to_map(&self) -> PropMap {
647        let mut map = PropMap::new();
648        map.insert("address".into(), Variant(Box::new(self.address.clone())));
649        map.insert(
650            "prefix-length".into(),
651            Variant(Box::new(self.prefix_length)),
652        );
653        if self.gateway.is_some() {
654            map.insert(
655                "gateway".into(),
656                Variant(Box::new(self.gateway.clone().unwrap())),
657            );
658        }
659        if self.metric.is_some() {
660            map.insert("metric".into(), Variant(Box::new(self.metric.unwrap())));
661        }
662        map
663    }
664}
665
666#[derive(Debug, Default)]
667pub enum DNSMethod4 {
668    #[default]
669    AUTO,
670    MANUAL,
671    LINKLOCAL,
672    SHARED,
673    DISABLED,
674}
675
676impl FromStr for DNSMethod4 {
677    type Err = ConversionError;
678
679    fn from_str(s: &str) -> Result<Self, Self::Err> {
680        match s {
681            "auto" => Ok(DNSMethod4::AUTO),
682            "manual" => Ok(DNSMethod4::MANUAL),
683            "link-local" => Ok(DNSMethod4::LINKLOCAL),
684            "shared" => Ok(DNSMethod4::SHARED),
685            _ => Ok(DNSMethod4::DISABLED),
686        }
687    }
688}
689
690impl ToString for DNSMethod4 {
691    fn to_string(&self) -> String {
692        match self {
693            DNSMethod4::AUTO => String::from("auto"),
694            DNSMethod4::MANUAL => String::from("manual"),
695            DNSMethod4::LINKLOCAL => String::from("link-local"),
696            DNSMethod4::SHARED => String::from("shared"),
697            DNSMethod4::DISABLED => String::from("disabled"),
698        }
699    }
700}
701
702impl Enum for DNSMethod4 {
703    fn from_i32(num: i32) -> Self {
704        match num {
705            0 => DNSMethod4::AUTO,
706            1 => DNSMethod4::MANUAL,
707            2 => DNSMethod4::LINKLOCAL,
708            3 => DNSMethod4::SHARED,
709            _ => DNSMethod4::DISABLED,
710        }
711    }
712
713    fn to_i32(&self) -> i32 {
714        match self {
715            DNSMethod4::AUTO => 0,
716            DNSMethod4::MANUAL => 1,
717            DNSMethod4::LINKLOCAL => 2,
718            DNSMethod4::SHARED => 3,
719            DNSMethod4::DISABLED => 4,
720        }
721    }
722}
723
724#[derive(Debug, Default)]
725pub enum DNSMethod6 {
726    #[default]
727    AUTO,
728    DHCP,
729    MANUAL,
730    LINKLOCAL,
731    SHARED,
732    DISABLED,
733}
734
735impl FromStr for DNSMethod6 {
736    type Err = ConversionError;
737
738    fn from_str(s: &str) -> Result<Self, Self::Err> {
739        match s {
740            "auto" => Ok(DNSMethod6::AUTO),
741            "dhcp" => Ok(DNSMethod6::DHCP),
742            "manual" => Ok(DNSMethod6::MANUAL),
743            "link-local" => Ok(DNSMethod6::LINKLOCAL),
744            "shared" => Ok(DNSMethod6::SHARED),
745            _ => Ok(DNSMethod6::DISABLED),
746        }
747    }
748}
749
750impl ToString for DNSMethod6 {
751    fn to_string(&self) -> String {
752        match self {
753            DNSMethod6::AUTO => String::from("auto"),
754            DNSMethod6::DHCP => String::from("dhcp"),
755            DNSMethod6::MANUAL => String::from("manual"),
756            DNSMethod6::LINKLOCAL => String::from("link-local"),
757            DNSMethod6::SHARED => String::from("shared"),
758            DNSMethod6::DISABLED => String::from("disabled"),
759        }
760    }
761}
762
763impl Enum for DNSMethod6 {
764    fn from_i32(num: i32) -> Self {
765        match num {
766            0 => DNSMethod6::AUTO,
767            1 => DNSMethod6::DHCP,
768            2 => DNSMethod6::MANUAL,
769            3 => DNSMethod6::LINKLOCAL,
770            4 => DNSMethod6::SHARED,
771            _ => DNSMethod6::DISABLED,
772        }
773    }
774
775    fn to_i32(&self) -> i32 {
776        match self {
777            DNSMethod6::AUTO => 0,
778            DNSMethod6::DHCP => 1,
779            DNSMethod6::MANUAL => 2,
780            DNSMethod6::LINKLOCAL => 3,
781            DNSMethod6::SHARED => 4,
782            DNSMethod6::DISABLED => 5,
783        }
784    }
785}
786
787#[derive(Debug, Default)]
788pub struct IPV4Settings {
789    pub address_data: Vec<Address>,
790    pub dns: Vec<Vec<u8>>,
791    pub dns_options: Vec<String>,
792    pub dns_priority: i32,
793    pub dns_search: Vec<String>,
794    pub gateway: String,
795    pub ignore_auto_dns: bool,
796    pub ignore_auto_dns_routes: bool,
797    pub may_fail: bool,
798    pub dns_method: DNSMethod4,
799    pub never_default: bool,
800    pub route_data: Vec<Address>,
801}
802
803impl PropMapConvert for IPV4Settings {
804    fn from_propmap(map: PropMap) -> Self {
805        println!("ipv4 debug");
806        for (key, val) in map.iter() {
807            dbg!(key);
808            dbg!(val);
809        }
810        let address_data = get_addresses(&map, "address-data");
811        let dns: Vec<Vec<u8>>;
812        let dns_opt: Option<&Vec<Vec<u8>>> = prop_cast(&map, "dns");
813        if dns_opt.is_none() {
814            dns = Vec::new();
815        } else {
816            dns = dns_opt.unwrap().clone();
817        }
818        let dns_options: Vec<String>;
819        let dns_options_opt: Option<&Vec<String>> = prop_cast(&map, "dns-options");
820        if dns_options_opt.is_none() {
821            dns_options = Vec::new();
822        } else {
823            dns_options = dns_options_opt.unwrap().clone();
824        }
825        let dns_priority = *prop_cast(&map, "dns-priority").unwrap_or(&0);
826        let dns_search: Vec<String>;
827        let dns_search_opt: Option<&Vec<String>> = prop_cast(&map, "dns-search");
828        if dns_search_opt.is_none() {
829            dns_search = Vec::new();
830        } else {
831            dns_search = dns_search_opt.unwrap().clone();
832        }
833        let gateway: String;
834        let gateway_opt: Option<&String> = prop_cast(&map, "gateway");
835        if gateway_opt.is_none() {
836            gateway = String::from("");
837        } else {
838            gateway = gateway_opt.unwrap().clone();
839        }
840        let ignore_auto_dns = *prop_cast(&map, "ignore-auto-dns").unwrap_or(&false);
841        let ignore_auto_dns_routes = *prop_cast(&map, "ignore-auto-dns-routes").unwrap_or(&false);
842        let may_fail = *prop_cast(&map, "may-fail").unwrap_or(&true);
843        let dns_method: DNSMethod4;
844        let method_opt: Option<&String> = prop_cast(&map, "method");
845        if method_opt.is_none() {
846            dns_method = DNSMethod4::DISABLED;
847        } else {
848            dns_method = DNSMethod4::from_str(method_opt.unwrap().as_str()).unwrap();
849        }
850        let never_default = *prop_cast(&map, "never-default").unwrap_or(&true);
851        let route_data = get_addresses(&map, "route-data");
852        Self {
853            address_data,
854            dns,
855            dns_options,
856            dns_priority,
857            dns_search,
858            gateway,
859            ignore_auto_dns,
860            ignore_auto_dns_routes,
861            may_fail,
862            dns_method,
863            never_default,
864            route_data,
865        }
866    }
867
868    fn to_propmap(&self, map: &mut PropMap) {
869        let mut addresses = Vec::new();
870        for address in self.address_data.iter() {
871            addresses.push(address.to_map());
872        }
873        map.insert("address-data".into(), Variant(Box::new(addresses)));
874        map.insert("dns".into(), Variant(Box::new(self.dns.clone())));
875        map.insert(
876            "dns-options".into(),
877            Variant(Box::new(self.dns_options.clone())),
878        );
879        map.insert("dns-priority".into(), Variant(Box::new(self.dns_priority)));
880        map.insert(
881            "dns-search".into(),
882            Variant(Box::new(self.dns_search.clone())),
883        );
884        map.insert("gateway".into(), Variant(Box::new(self.gateway.clone())));
885        map.insert(
886            "ignore-auto-dns".into(),
887            Variant(Box::new(self.ignore_auto_dns)),
888        );
889        map.insert(
890            "ignore-auto-dns-routes".into(),
891            Variant(Box::new(self.ignore_auto_dns_routes)),
892        );
893        map.insert("may-fail".into(), Variant(Box::new(self.may_fail)));
894        map.insert(
895            "dns-method".into(),
896            Variant(Box::new(self.dns_method.to_i32())),
897        );
898        map.insert(
899            "never-default".into(),
900            Variant(Box::new(self.never_default)),
901        );
902        let mut data = Vec::new();
903        for address in self.route_data.iter() {
904            data.push(address.to_map());
905        }
906        map.insert("route-data".into(), Variant(Box::new(data)));
907    }
908}
909
910#[derive(Debug, Default)]
911pub enum IPV6PrivacyMode {
912    DISABLED,
913    ENABLEDPEFERPUBLIC,
914    ENABLEDPEFERTEMPORARY,
915    #[default]
916    UNKNOWN,
917}
918
919impl FromStr for IPV6PrivacyMode {
920    type Err = ConversionError;
921
922    fn from_str(s: &str) -> Result<Self, Self::Err> {
923        match s {
924            "disabled" => Ok(IPV6PrivacyMode::DISABLED),
925            "enabled-prefer-public" => Ok(IPV6PrivacyMode::ENABLEDPEFERPUBLIC),
926            "enabled-prefer-temporary" => Ok(IPV6PrivacyMode::ENABLEDPEFERTEMPORARY),
927            _ => Ok(IPV6PrivacyMode::UNKNOWN),
928        }
929    }
930}
931
932impl ToString for IPV6PrivacyMode {
933    fn to_string(&self) -> String {
934        match self {
935            IPV6PrivacyMode::UNKNOWN => String::from("unknown"),
936            IPV6PrivacyMode::DISABLED => String::from("disabled"),
937            IPV6PrivacyMode::ENABLEDPEFERPUBLIC => String::from("enabled-prefer-public"),
938            IPV6PrivacyMode::ENABLEDPEFERTEMPORARY => String::from("enabled-prefer-temporary"),
939        }
940    }
941}
942
943impl Enum for IPV6PrivacyMode {
944    fn from_i32(num: i32) -> Self {
945        match num {
946            -1 => IPV6PrivacyMode::UNKNOWN,
947            0 => IPV6PrivacyMode::DISABLED,
948            1 => IPV6PrivacyMode::ENABLEDPEFERPUBLIC,
949            _ => IPV6PrivacyMode::ENABLEDPEFERTEMPORARY,
950        }
951    }
952
953    fn to_i32(&self) -> i32 {
954        match self {
955            IPV6PrivacyMode::UNKNOWN => -1,
956            IPV6PrivacyMode::DISABLED => 0,
957            IPV6PrivacyMode::ENABLEDPEFERPUBLIC => 1,
958            IPV6PrivacyMode::ENABLEDPEFERTEMPORARY => 2,
959        }
960    }
961}
962
963#[derive(Debug, Default)]
964pub struct IPV6Settings {
965    pub address_data: Vec<Address>,
966    pub dns: Vec<Vec<u8>>,
967    pub dns_options: Vec<String>,
968    pub dns_priority: i32,
969    pub dns_search: Vec<String>,
970    pub gateway: String,
971    pub ignore_auto_dns: bool,
972    pub ignore_auto_dns_routes: bool,
973    pub ipv6_privacy: IPV6PrivacyMode,
974    pub may_fail: bool,
975    pub dns_method: DNSMethod6,
976    pub never_default: bool,
977    pub route_data: Vec<Address>,
978}
979
980impl PropMapConvert for IPV6Settings {
981    fn from_propmap(map: PropMap) -> Self {
982        println!("ipv6 debug");
983        for (key, val) in map.iter() {
984            dbg!(key);
985            dbg!(val);
986        }
987        let address_data = get_addresses(&map, "address-data");
988        let dns: Vec<Vec<u8>>;
989        let dns_opt: Option<&Vec<Vec<u8>>> = prop_cast(&map, "dns");
990        if dns_opt.is_none() {
991            dns = Vec::new();
992        } else {
993            dns = dns_opt.unwrap().clone();
994        }
995        let dns_options: Vec<String>;
996        let dns_options_opt: Option<&Vec<String>> = prop_cast(&map, "dns-options");
997        if dns_options_opt.is_none() {
998            dns_options = Vec::new();
999        } else {
1000            dns_options = dns_options_opt.unwrap().clone();
1001        }
1002        let dns_priority = *prop_cast(&map, "dns-priority").unwrap_or(&0);
1003        let dns_search: Vec<String>;
1004        let dns_search_opt: Option<&Vec<String>> = prop_cast(&map, "dns-search");
1005        if dns_search_opt.is_none() {
1006            dns_search = Vec::new();
1007        } else {
1008            dns_search = dns_search_opt.unwrap().clone();
1009        }
1010        let gateway: String;
1011        let gateway_opt: Option<&String> = prop_cast(&map, "gateway");
1012        if gateway_opt.is_none() {
1013            gateway = String::from("");
1014        } else {
1015            gateway = gateway_opt.unwrap().clone();
1016        }
1017        let ignore_auto_dns = *prop_cast(&map, "ignore-auto-dns").unwrap_or(&false);
1018        let ignore_auto_dns_routes = *prop_cast(&map, "ignore-auto-dns-routes").unwrap_or(&false);
1019        let ipv6_privacy = IPV6PrivacyMode::from_i32(*prop_cast(&map, "ip6-privacy").unwrap_or(&-1));
1020        let may_fail = *prop_cast(&map, "may-fail").unwrap_or(&true);
1021        let dns_method: DNSMethod6;
1022        let method_opt: Option<&String> = prop_cast(&map, "method");
1023        if method_opt.is_none() {
1024            dns_method = DNSMethod6::DISABLED;
1025        } else {
1026            dns_method = DNSMethod6::from_str(method_opt.unwrap().as_str()).unwrap();
1027        }
1028        let never_default = *prop_cast(&map, "never-default").unwrap_or(&true);
1029        let route_data = get_addresses(&map, "route-data");
1030        Self {
1031            address_data,
1032            dns,
1033            dns_options,
1034            dns_priority,
1035            dns_search,
1036            gateway,
1037            ignore_auto_dns,
1038            ignore_auto_dns_routes,
1039            ipv6_privacy,
1040            may_fail,
1041            dns_method,
1042            never_default,
1043            route_data,
1044        }
1045    }
1046
1047    fn to_propmap(&self, map: &mut PropMap) {
1048        let mut addresses = Vec::new();
1049        for address in self.address_data.iter() {
1050            addresses.push(address.to_map());
1051        }
1052        map.insert("address-data".into(), Variant(Box::new(addresses)));
1053        map.insert("dns".into(), Variant(Box::new(self.dns.clone())));
1054        map.insert(
1055            "dns-options".into(),
1056            Variant(Box::new(self.dns_options.clone())),
1057        );
1058        map.insert("dns-priority".into(), Variant(Box::new(self.dns_priority)));
1059        map.insert(
1060            "dns-search".into(),
1061            Variant(Box::new(self.dns_search.clone())),
1062        );
1063        map.insert("gateway".into(), Variant(Box::new(self.gateway.clone())));
1064        map.insert(
1065            "ignore-auto-dns".into(),
1066            Variant(Box::new(self.ignore_auto_dns)),
1067        );
1068        map.insert(
1069            "ignore-auto-dns-routes".into(),
1070            Variant(Box::new(self.ignore_auto_dns_routes)),
1071        );
1072        map.insert(
1073            "ipv6-privacy".into(),
1074            Variant(Box::new(self.ipv6_privacy.to_i32())),
1075        );
1076        map.insert("may-fail".into(), Variant(Box::new(self.may_fail)));
1077        map.insert(
1078            "dns-method".into(),
1079            Variant(Box::new(self.dns_method.to_i32())),
1080        );
1081        map.insert(
1082            "never-default".into(),
1083            Variant(Box::new(self.never_default)),
1084        );
1085        let mut data = Vec::new();
1086        for address in self.route_data.iter() {
1087            data.push(address.to_map());
1088        }
1089        map.insert("route-data".into(), Variant(Box::new(data)));
1090    }
1091}
1092
1093fn get_addresses(map: &PropMap, address_type: &'static str) -> Vec<Address> {
1094    let mut address_data: Vec<Address> = Vec::new();
1095    let address_data_opt: Option<&Vec<PropMap>> = prop_cast(map, address_type);
1096    if address_data_opt.is_some() {
1097        for entry in address_data_opt.unwrap() {
1098            let address: String;
1099            let prefix_length: u32;
1100            let gateway: Option<String>;
1101            let metric: Option<u32>;
1102            let address_opt = entry.get("address");
1103            let prefix_length_opt = entry.get("prefix");
1104            let gateway_opt = entry.get("gateway");
1105            let metric_opt = entry.get("metric");
1106            if address_data_opt.is_none() {
1107                address = String::from("");
1108            } else {
1109                address = arg::cast::<String>(address_opt.unwrap()).unwrap().clone();
1110            }
1111            if prefix_length_opt.is_none() {
1112                prefix_length = 0;
1113            } else {
1114                prefix_length = *arg::cast::<u32>(prefix_length_opt.unwrap()).unwrap();
1115            }
1116            if gateway_opt.is_none() {
1117                gateway = None;
1118            } else {
1119                gateway = arg::cast::<Option<String>>(address_opt.unwrap()).unwrap().clone();
1120            }
1121            if metric_opt.is_none() {
1122                metric = None;
1123            } else {
1124                metric = *arg::cast::<Option<u32>>(gateway_opt.unwrap()).unwrap();
1125            }
1126
1127            address_data.push(Address {
1128                address,
1129                prefix_length,
1130                gateway,
1131                metric,
1132            })
1133        }
1134    }
1135    address_data
1136}
1137
1138#[derive(Debug, Default)]
1139pub struct ConnectionSettings {
1140    pub autoconnect: bool,
1141    pub autoconnect_priority: i32,
1142    pub metered: i32,
1143    pub name: String,
1144    pub device_type: String,
1145    pub uuid: String,
1146    pub zone: Trust,
1147}
1148
1149impl PropMapConvert for ConnectionSettings {
1150    fn from_propmap(map: PropMap) -> Self {
1151        println!("settings debug");
1152        for (key, val) in map.iter() {
1153            dbg!(key);
1154            dbg!(val);
1155        }
1156        let autoconnect = prop_cast(&map, "autoconnect");
1157        let autoconnect_priority = prop_cast(&map, "autoconnect-priority");
1158        let uuid: String;
1159        let name: String;
1160        let device_type: String;
1161        let metered = prop_cast(&map, "metered");
1162        let zone: Trust;
1163        let zone_opt: Option<&String> = prop_cast(&map, "trust");
1164        if zone_opt.is_none() {
1165            zone = Trust::from_str("").ok().unwrap();
1166        } else {
1167            zone = Trust::from_str(zone_opt.unwrap().as_str()).ok().unwrap();
1168        }
1169
1170        let uuid_opt: Option<&String> = prop_cast(&map, "uuid");
1171        if uuid_opt.is_none() {
1172            uuid = String::from("");
1173        } else {
1174            uuid = uuid_opt.unwrap().clone();
1175        }
1176        let name_opt: Option<&String> = prop_cast(&map, "name");
1177        if name_opt.is_none() {
1178            name = String::from("");
1179        } else {
1180            name = name_opt.unwrap().clone();
1181        }
1182        let device_type_opt: Option<&String> = prop_cast(&map, "type");
1183        if device_type_opt.is_none() {
1184            device_type = String::from("");
1185        } else {
1186            device_type = device_type_opt.unwrap().clone();
1187        }
1188        Self {
1189            autoconnect: *autoconnect.unwrap_or(&false),
1190            autoconnect_priority: *autoconnect_priority.unwrap_or(&-1),
1191            metered: *metered.unwrap_or(&-1),
1192            name,
1193            device_type,
1194            uuid,
1195            zone,
1196        }
1197    }
1198
1199    fn to_propmap(&self, map: &mut PropMap) {
1200        map.insert("autoconnect".into(), Variant(Box::new(self.autoconnect)));
1201        map.insert(
1202            "autoconnect-priority".into(),
1203            Variant(Box::new(self.autoconnect_priority)),
1204        );
1205        map.insert("metered".into(), Variant(Box::new(self.metered)));
1206        map.insert("name".into(), Variant(Box::new(self.name.clone())));
1207        map.insert(
1208            "device-type".into(),
1209            Variant(Box::new(self.device_type.clone())),
1210        );
1211        map.insert("uuid".into(), Variant(Box::new(self.uuid.clone())));
1212        map.insert("zone".into(), Variant(Box::new(self.zone.to_i32())));
1213    }
1214}
1215
1216#[derive(Debug, Default, Clone)]
1217pub enum SecretSettingsFlag {
1218    #[default]
1219    NONE,
1220    AGENT_OWNED,
1221    NOT_SAVED,
1222    NOT_REQUIRED,
1223}
1224
1225impl Enum for SecretSettingsFlag {
1226    fn from_i32(num: i32) -> Self {
1227        match num {
1228            0 => SecretSettingsFlag::NONE,
1229            1 => SecretSettingsFlag::AGENT_OWNED,
1230            2 => SecretSettingsFlag::NOT_SAVED,
1231            _ => SecretSettingsFlag::NOT_REQUIRED,
1232        }
1233    }
1234
1235    fn to_i32(&self) -> i32 {
1236        match self {
1237            SecretSettingsFlag::NONE => 0,
1238            SecretSettingsFlag::AGENT_OWNED => 1,
1239            SecretSettingsFlag::NOT_SAVED => 2,
1240            SecretSettingsFlag::NOT_REQUIRED => 3,
1241        }
1242    }
1243}
1244
1245#[derive(Debug, Default, Clone)]
1246pub enum WEPKeyType {
1247    #[default]
1248    UNKNOWN,
1249    KEY,
1250    PASSPHRASE,
1251    LAST,
1252}
1253
1254impl Enum for WEPKeyType {
1255    fn from_i32(num: i32) -> Self {
1256        match num {
1257            0 => WEPKeyType::UNKNOWN,
1258            1 => WEPKeyType::KEY,
1259            2 => WEPKeyType::PASSPHRASE,
1260            _ => WEPKeyType::LAST,
1261        }
1262    }
1263
1264    fn to_i32(&self) -> i32 {
1265        match self {
1266            WEPKeyType::UNKNOWN => 0,
1267            WEPKeyType::KEY => 1,
1268            WEPKeyType::PASSPHRASE => 2,
1269            WEPKeyType::LAST => 3,
1270        }
1271    }
1272}
1273
1274#[derive(Debug, Default, Clone)]
1275pub struct WifiSecuritySettings {
1276    pub authentication_algorithm: String,
1277    pub group: Vec<String>,
1278    pub key_management: String,
1279    pub leap_password: String,
1280    pub leap_password_flags: SecretSettingsFlag,
1281    pub leap_username: String,
1282    pub name: String,
1283    pub pairwise: Vec<String>,
1284    pub proto: Vec<String>,
1285    pub psk: String,
1286    pub psk_flags: SecretSettingsFlag,
1287    pub wep_key_flags: SecretSettingsFlag,
1288    pub wep_key_type: WEPKeyType,
1289    pub wep_key0: String,
1290    pub wep_key1: String,
1291    pub wep_key2: String,
1292    pub wep_key3: String,
1293    pub wep_tx_keyidx: u32,
1294}
1295
1296impl PropMapConvert for WifiSecuritySettings {
1297    fn from_propmap(map: PropMap) -> Self {
1298        println!("secret settings debug");
1299        let authentication_algorithm: String;
1300        let authentication_algorithm_opt: Option<&String> = prop_cast(&map, "auth-alg");
1301        if authentication_algorithm_opt.is_none() {
1302            authentication_algorithm = String::from("");
1303        } else {
1304            authentication_algorithm = authentication_algorithm_opt.unwrap().clone();
1305        }
1306        let group: Vec<String>;
1307        let group_opt: Option<&Vec<String>> = prop_cast(&map, "group");
1308        if group_opt.is_none() {
1309            group = Vec::new();
1310        } else {
1311            group = group_opt.unwrap().clone();
1312        }
1313        let key_management: String;
1314        let key_management_opt: Option<&String> = prop_cast(&map, "key-mgmt");
1315        if key_management_opt.is_none() {
1316            key_management = String::from("");
1317        } else {
1318            key_management = key_management_opt.unwrap().clone();
1319        }
1320        let leap_password: String;
1321        let leap_password_opt: Option<&String> = prop_cast(&map, "leap-password");
1322        if leap_password_opt.is_none() {
1323            leap_password = String::from("");
1324        } else {
1325            leap_password = leap_password_opt.unwrap().clone();
1326        }
1327        let leap_password_flags_opt: Option<&u32> = prop_cast(&map, "leap-password-flags");
1328        let leap_password_flags = SecretSettingsFlag::from_i32(*leap_password_flags_opt.unwrap_or(&0) as i32);
1329        let leap_username: String;
1330        let leap_username_opt: Option<&String> = prop_cast(&map, "leap-username");
1331        if leap_username_opt.is_none() {
1332            leap_username = String::from("");
1333        } else {
1334            leap_username = leap_username_opt.unwrap().clone();
1335        }
1336        let name: String;
1337        let name_opt: Option<&String> = prop_cast(&map, "name");
1338        if name_opt.is_none() {
1339            name = String::from("");
1340        } else {
1341            name = name_opt.unwrap().clone();
1342        }
1343        let pairwise: Vec<String>;
1344        let pairwise_opt: Option<&Vec<String>> = prop_cast(&map, "pairwise");
1345        if pairwise_opt.is_none() {
1346            pairwise = Vec::new();
1347        } else {
1348            pairwise = pairwise_opt.unwrap().clone();
1349        }
1350        let proto: Vec<String>;
1351        let proto_opt: Option<&Vec<String>> = prop_cast(&map, "proto");
1352        if proto_opt.is_none() {
1353            proto = Vec::new();
1354        } else {
1355            proto = proto_opt.unwrap().clone();
1356        }
1357        let psk: String;
1358        let psk_opt: Option<&String> = prop_cast(&map, "psk");
1359        if psk_opt.is_none() {
1360            psk = String::from("");
1361        } else {
1362            psk = psk_opt.unwrap().clone();
1363        }
1364        let _psk_flags_opt: Option<&u32> = prop_cast(&map, "psk-flags");
1365        let psk_flags = SecretSettingsFlag::from_i32(*leap_password_flags_opt.unwrap_or(&0) as i32);
1366        let _wep_key_flags_opt: Option<&u32> = prop_cast(&map, "wep-key-flags");
1367        let wep_key_flags = SecretSettingsFlag::from_i32(*leap_password_flags_opt.unwrap_or(&0) as i32);
1368        let wep_key_type_opt: Option<&u32> = prop_cast(&map, "wep-key-type");
1369        let wep_key_type = WEPKeyType::from_i32(*wep_key_type_opt.unwrap_or(&0) as i32);
1370        let wep_key0: String;
1371        let wep_key0_opt: Option<&String> = prop_cast(&map, "wep-key0");
1372        if wep_key0_opt.is_none() {
1373            wep_key0 = String::from("");
1374        } else {
1375            wep_key0 = wep_key0_opt.unwrap().clone();
1376        }
1377        let wep_key1: String;
1378        let wep_key1_opt: Option<&String> = prop_cast(&map, "wep-key1");
1379        if wep_key1_opt.is_none() {
1380            wep_key1 = String::from("");
1381        } else {
1382            wep_key1 = wep_key1_opt.unwrap().clone();
1383        }
1384        let wep_key2: String;
1385        let wep_key2_opt: Option<&String> = prop_cast(&map, "wep-key2");
1386        if wep_key2_opt.is_none() {
1387            wep_key2 = String::from("");
1388        } else {
1389            wep_key2 = wep_key2_opt.unwrap().clone();
1390        }
1391        let wep_key3: String;
1392        let wep_key3_opt: Option<&String> = prop_cast(&map, "wep-key3");
1393        if wep_key3_opt.is_none() {
1394            wep_key3 = String::from("");
1395        } else {
1396            wep_key3 = wep_key3_opt.unwrap().clone();
1397        }
1398        let wep_tx_keyidx: Option<&u32> = prop_cast(&map, "wep-tx-keyidx");
1399        Self {
1400            authentication_algorithm,
1401            group,
1402            key_management,
1403            leap_password,
1404            leap_password_flags,
1405            leap_username,
1406            name,
1407            pairwise,
1408            proto,
1409            psk,
1410            psk_flags,
1411            wep_key_flags,
1412            wep_key_type,
1413            wep_key0,
1414            wep_key1,
1415            wep_key2,
1416            wep_key3,
1417            wep_tx_keyidx: *wep_tx_keyidx.unwrap_or(&0),
1418        }
1419    }
1420
1421    fn to_propmap(&self, map: &mut PropMap) {
1422        map.insert(
1423            "auth-alg".into(),
1424            Variant(Box::new(self.authentication_algorithm.clone())),
1425        );
1426        map.insert("group".into(), Variant(Box::new(self.group.clone())));
1427        map.insert(
1428            "key-mgmt".into(),
1429            Variant(Box::new(self.key_management.clone())),
1430        );
1431        map.insert(
1432            "leap-password".into(),
1433            Variant(Box::new(self.leap_password.clone())),
1434        );
1435        map.insert(
1436            "leap-password-flags".into(),
1437            Variant(Box::new(self.leap_password_flags.to_i32())),
1438        );
1439        map.insert(
1440            "leap-username".into(),
1441            Variant(Box::new(self.leap_username.clone())),
1442        );
1443        map.insert("name".into(), Variant(Box::new(self.name.clone())));
1444        map.insert("pairwise".into(), Variant(Box::new(self.pairwise.clone())));
1445        map.insert("proto".into(), Variant(Box::new(self.proto.clone())));
1446        map.insert("psk".into(), Variant(Box::new(self.psk.clone())));
1447        map.insert(
1448            "psk-flags".into(),
1449            Variant(Box::new(self.psk_flags.to_i32())),
1450        );
1451        map.insert(
1452            "wep-key-type".into(),
1453            Variant(Box::new(self.wep_key_type.to_i32())),
1454        );
1455        map.insert("wep-key0".into(), Variant(Box::new(self.wep_key0.clone())));
1456        map.insert("wep-key1".into(), Variant(Box::new(self.wep_key1.clone())));
1457        map.insert("wep-key2".into(), Variant(Box::new(self.wep_key2.clone())));
1458        map.insert("wep-key3".into(), Variant(Box::new(self.wep_key3.clone())));
1459        map.insert(
1460            "wep-tx-keyidx".into(),
1461            Variant(Box::new(self.wep_tx_keyidx)),
1462        );
1463    }
1464}