1use crate::Hex;
63use crate::Tristate;
64use kconfig_parser::ast::ConfigType;
65use kconfig_parser::escape_string;
66use kconfig_parser::parse_string;
67use std::cmp::Ordering;
68use std::fmt::Display;
69use std::ops::Not;
70
71#[derive(PartialEq, Eq, Clone, Debug)]
73pub struct Variant {
74    data: Data,
75}
76
77impl Variant {
78    pub fn datatype(&self) -> VariantDataType {
79        match &self.data {
80            Data::String(_) => VariantDataType::String,
81            Data::Bool(_) => VariantDataType::Bool,
82            Data::Hex(_) => VariantDataType::Hex,
83            Data::Int(_) => VariantDataType::Int,
84            Data::Tristate(_) => VariantDataType::Tristate,
85        }
86    }
87
88    pub fn new_typed(vdt: &VariantDataType) -> Self {
89        Self {
90            data: match vdt {
91                &VariantDataType::String => Data::String(String::default()),
92                &VariantDataType::Bool => Data::Bool(bool::default()),
93                &VariantDataType::Hex => Data::Hex(Hex::default()),
94                &VariantDataType::Int => Data::Int(i64::default()),
95                &VariantDataType::Tristate => Data::Tristate(Tristate::default()),
96            },
97        }
98    }
99
100    pub fn convert_into(&self, vdt: &VariantDataType) -> Self {
101        Self {
102            data: match vdt {
103                &VariantDataType::String => Data::String(self.clone().into()),
104                &VariantDataType::Bool => Data::Bool(self.clone().into()),
105                &VariantDataType::Hex => Data::Hex(self.clone().into()),
106                &VariantDataType::Int => Data::Int(self.clone().into()),
107                &VariantDataType::Tristate => Data::Tristate(self.clone().into()),
108            },
109        }
110    }
111
112    pub fn to_bool(&self) -> bool {
127        match &self.data {
128            Data::String(s) => {
129                if s == "y" || s == "Y" {
130                    true
131                } else {
132                    false
133                }
134            }
135            Data::Bool(b) => *b,
136            Data::Tristate(t) => match t {
137                &Tristate::FALSE => false,
138                _ => true,
139            },
140            Data::Hex(h) => *h != Hex::from(0),
141            Data::Int(i) => *i != 0,
142        }
143    }
144
145    pub fn to_tristate(&self) -> Tristate {
159        match &self.data {
160            Data::String(s) => {
161                if s == "y" || s == "Y" {
162                    Tristate::TRUE
163                } else if s == "m" || s == "M" {
164                    Tristate::MAYBE
165                } else {
166                    Tristate::FALSE
167                }
168            }
169            Data::Bool(b) => Tristate::from(*b),
170            Data::Tristate(t) => *t,
171            Data::Hex(h) => {
172                if *h != Hex::from(0) {
173                    Tristate::TRUE
174                } else {
175                    Tristate::FALSE
176                }
177            }
178            Data::Int(i) => {
179                if *i != 0 {
180                    Tristate::TRUE
181                } else {
182                    Tristate::FALSE
183                }
184            }
185        }
186    }
187
188    pub fn to_hex(&self) -> Hex {
205        match &self.data {
206            Data::String(s) => match Self::parse_hex(s) {
207                Some(Data::Hex(h)) => h,
208                _ => {
209                    if s == "y" || s == "Y" {
210                        Hex::from(1)
211                    } else {
212                        Hex::from(0)
213                    }
214                }
215            },
216            Data::Bool(b) => match b {
217                true => Hex::from(1),
218                false => Hex::from(0),
219            },
220            Data::Tristate(b) => match b {
221                &Tristate::TRUE => Hex::from(1),
222                &Tristate::FALSE => Hex::from(0),
223                &Tristate::MAYBE => Hex::from(1),
224            },
225            Data::Hex(h) => *h,
226            Data::Int(i) => Hex::from(*i as u64),
227        }
228    }
229
230    pub fn to_int(&self) -> i64 {
247        match &self.data {
248            Data::String(s) => match Self::parse_int(s) {
249                Some(Data::Int(i)) => i,
250                _ => {
251                    if s == "y" || s == "Y" {
252                        1i64
253                    } else {
254                        0i64
255                    }
256                }
257            },
258            Data::Bool(b) => match b {
259                true => 1,
260                false => 0,
261            },
262            Data::Tristate(b) => match b {
263                &Tristate::TRUE => 1,
264                &Tristate::FALSE => 0,
265                &Tristate::MAYBE => 1,
266            },
267            Data::Hex(h) => {
268                let value: u64 = (*h).into();
269                value as i64
270            }
271            Data::Int(i) => *i,
272        }
273    }
274
275    fn to_string(&self) -> String {
290        match &self.data {
291            Data::String(s) => s.clone(),
292            Data::Bool(b) => match b {
293                &true => "y".to_owned(),
294                &false => "n".to_owned(),
295            },
296            Data::Tristate(t) => match t {
297                &Tristate::TRUE => "y".to_owned(),
298                &Tristate::FALSE => "n".to_owned(),
299                &Tristate::MAYBE => "m".to_owned(),
300            },
301            Data::Hex(h) => h.to_string(),
302            Data::Int(i) => i.to_string(),
303        }
304    }
305
306    fn parse_hex(v: &str) -> Option<Data> {
307        let v = v.replace("_", "").replace(" ", "");
308        let mut chars = v.chars();
309
310        let mut result = 0u64;
311
312        if let Some(next_char) = chars.next() {
313            if next_char == '0' {
314                if let Some(next_char) = chars.next() {
316                    if next_char == 'x' || next_char == 'X' {
317                        let mut repeat = true;
319
320                        while repeat {
321                            repeat = if let Some(c) = chars.next() {
322                                result <<= 4u64;
323                                match c.to_digit(16) {
324                                    Some(v) => result |= v as u64,
325                                    None => return None,
326                                }
327                                true
328                            } else {
329                                false
330                            }
331                        }
332
333                        return Some(Data::Hex(Hex::from(result)));
334                    }
335                }
336            }
337        }
338
339        None
340    }
341
342    fn parse_int(v: &str) -> Option<Data> {
343        let v = v.replace("_", "").replace(" ", "");
344        let chars = v.chars();
345
346        let mut result = 0i64;
347
348        let mut is_negative = false;
349        let mut is_first = true;
350
351        for c in chars {
352            if is_first && c == '-' {
353                is_negative = true;
354                continue;
355            }
356            is_first = false;
357            result *= 10;
358            match c.to_digit(10) {
359                Some(v) => result += v as i64,
360                None => return None,
361            }
362        }
363
364        if is_negative {
365            result = 0 - result;
366        }
367
368        return Some(Data::Int(result));
369    }
370
371    pub fn parse(v: &str) -> Self {
382        let data = if v == "y" || v == "Y" {
384            Data::Bool(true)
385        }
386        else if v == "n" || v == "N" {
388            Data::Bool(false)
389        } else if v == "m" || v == "M" {
391            Data::Tristate(Tristate::MAYBE)
392        } else {
393            if let Some(result) = Self::parse_int(v) {
395                result
396            } else if let Some(result) = Self::parse_hex(v) {
398                result
399            } else {
401                Data::String(v.to_string())
402            }
403        };
404
405        Self { data: data }
406    }
407
408    pub fn from_dot_config(v: &str) -> Self {
410        match parse_string(v) {
411            Ok(s) => Self {
412                data: Data::String(s),
413            },
414            Err(_) => Self::parse(v),
415        }
416    }
417
418    pub fn dot_config(&self) -> String {
421        match &self.data {
422            Data::Bool(b) => match b {
423                true => "y".to_owned(),
424                false => "n".to_owned(),
425            },
426            Data::Tristate(t) => match t {
427                &Tristate::TRUE => "y".to_owned(),
428                &Tristate::MAYBE => "m".to_owned(),
429                &Tristate::FALSE => "n".to_owned(),
430            },
431            Data::String(s) => escape_string(&s),
432            Data::Int(i) => i.to_string(),
433            Data::Hex(h) => h.to_string(),
434        }
435    }
436
437    pub fn transform(&self, vdt: VariantDataType) -> Variant {
439        match vdt {
440            VariantDataType::Bool => Variant::from(self.to_bool()),
441            VariantDataType::Hex => Variant::from(self.to_hex()),
442            VariantDataType::Int => Variant::from(self.to_int()),
443            VariantDataType::Tristate => Variant::from(self.to_tristate()),
444            VariantDataType::String => Variant::from(self.to_string()),
445        }
446    }
447}
448
449impl Display for Variant {
450    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
452        f.write_str(&self.to_string())
453    }
454}
455
456impl From<&str> for Variant {
457    fn from(v: &str) -> Self {
459        Self {
460            data: Data::String(v.to_string()),
461        }
462    }
463}
464
465impl From<String> for Variant {
466    fn from(v: String) -> Self {
468        Self {
469            data: Data::String(v),
470        }
471    }
472}
473
474impl From<bool> for Variant {
475    fn from(b: bool) -> Self {
477        Self {
478            data: Data::Bool(b),
479        }
480    }
481}
482
483impl From<Tristate> for Variant {
484    fn from(t: Tristate) -> Self {
486        Self {
487            data: Data::Tristate(t),
488        }
489    }
490}
491
492impl From<i64> for Variant {
493    fn from(i: i64) -> Self {
495        Self { data: Data::Int(i) }
496    }
497}
498
499impl From<Hex> for Variant {
500    fn from(h: Hex) -> Self {
502        Self { data: Data::Hex(h) }
503    }
504}
505
506impl Not for Variant {
507    type Output = Variant;
508
509    fn not(self) -> Self::Output {
514        if let Data::Bool(v) = &self.data {
515            Variant {
516                data: Data::Bool(!v),
517            }
518        } else {
519            let v = self.to_tristate();
520            Variant {
521                data: Data::Tristate(!v),
522            }
523        }
524    }
525}
526
527impl Into<bool> for Variant {
528    fn into(self) -> bool {
531        self.to_bool()
532    }
533}
534
535impl Into<String> for Variant {
536    fn into(self) -> String {
539        self.to_string()
540    }
541}
542
543impl Into<Tristate> for Variant {
544    fn into(self) -> Tristate {
547        self.to_tristate()
548    }
549}
550
551impl Into<i64> for Variant {
552    fn into(self) -> i64 {
555        self.to_int()
556    }
557}
558
559impl Into<Hex> for Variant {
560    fn into(self) -> Hex {
563        self.to_hex()
564    }
565}
566
567impl Ord for Variant {
568    fn cmp(&self, other: &Self) -> Ordering {
583        if self.datatype().numberlike() && other.datatype().numberlike() {
584            let me: i64 = self.clone().into();
585            let other: i64 = other.clone().into();
586            return me.cmp(&other);
587        }
588
589        if self.datatype().boollike() && other.datatype().boollike() {
590            let me: Tristate = self.clone().into();
591            let other: Tristate = other.clone().into();
592            return me.cmp(&other);
593        }
594
595        if self.datatype().numberlike() && other.datatype().boollike()
596            || self.datatype().boollike() && other.datatype().numberlike()
597        {
598            let me: Tristate = self.clone().into();
599            let other: Tristate = other.clone().into();
600            return me.cmp(&other);
601        }
602
603        let me: String = self.clone().into();
604        let other: String = self.clone().into();
605        me.cmp(&other)
606    }
607}
608
609impl PartialOrd for Variant {
610    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
611        Some(self.cmp(other))
612    }
613}
614
615#[derive(PartialEq, Eq, Clone, Debug)]
616enum Data {
617    String(String),
618    Bool(bool),
619    Tristate(Tristate),
620    Hex(Hex),
621    Int(i64),
622}
623
624#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug)]
625pub enum VariantDataType {
626    String,
628    Bool,
630    Tristate,
632    Hex,
634    Int,
636}
637
638impl VariantDataType {
639    pub(self) fn numberlike(&self) -> bool {
640        match self {
641            Self::Hex | Self::Int => true,
642            _ => false,
643        }
644    }
645
646    pub(self) fn boollike(&self) -> bool {
647        match self {
648            Self::Bool | Self::Tristate => true,
649            _ => false,
650        }
651    }
652}
653
654impl From<&ConfigType> for VariantDataType {
655    fn from(ct: &ConfigType) -> Self {
657        match ct {
658            ConfigType::Bool => Self::Bool,
659            ConfigType::String => Self::String,
660            ConfigType::Tristate => Self::Tristate,
661            ConfigType::Hex => Self::Hex,
662            ConfigType::Int => Self::Int,
663        }
664    }
665}
666
667impl Into<ConfigType> for VariantDataType {
668    fn into(self) -> ConfigType {
670        match self {
671            Self::Bool => ConfigType::Bool,
672            Self::String => ConfigType::String,
673            Self::Tristate => ConfigType::Tristate,
674            Self::Hex => ConfigType::Hex,
675            Self::Int => ConfigType::Int,
676        }
677    }
678}
679
680#[cfg(test)]
681mod tests {
682    use crate::Hex;
683    use crate::Tristate;
684    use crate::{Error, Variant, VariantDataType};
685    use kconfig_parser::ast::ConfigType;
686
687    #[test]
688    fn bool_variant_false() -> Result<(), Error> {
689        let result: bool = Variant::from(false).into();
690        assert_eq!(false, result);
691        let result: String = Variant::from(false).into();
692        assert_eq!("n".to_owned(), result);
693        let result: Tristate = Variant::from(false).into();
694        assert_eq!(Tristate::FALSE, result);
695        let result: i64 = Variant::from(false).into();
696        assert_eq!(0, result);
697        let result: Hex = Variant::from(false).into();
698        assert_eq!(Hex::from(0), result);
699        Ok(())
700    }
701
702    #[test]
703    fn bool_variant_true() -> Result<(), Error> {
704        let result: bool = Variant::from(true).into();
705        assert_eq!(true, result);
706        let result: String = Variant::from(true).into();
707        assert_eq!("y".to_owned(), result);
708        let result: Tristate = Variant::from(true).into();
709        assert_eq!(Tristate::TRUE, result);
710        let result: i64 = Variant::from(true).into();
711        assert_eq!(1, result);
712        let result: Hex = Variant::from(true).into();
713        assert_eq!(Hex::from(1), result);
714        Ok(())
715    }
716
717    #[test]
718    fn string_variant_falsely() -> Result<(), Error> {
719        let result: bool = Variant::from("n").into();
720        assert_eq!(false, result);
721        let result: String = Variant::from("n").into();
722        assert_eq!("n".to_owned(), result);
723        let result: Tristate = Variant::from("n").into();
724        assert_eq!(Tristate::FALSE, result);
725        let result: i64 = Variant::from("n").into();
726        assert_eq!(0, result);
727        let result: Hex = Variant::from("n").into();
728        assert_eq!(Hex::from(0), result);
729        Ok(())
730    }
731
732    #[test]
733    fn string_variant_maybe() -> Result<(), Error> {
734        let result: Tristate = Variant::from("m").into();
735        assert_eq!(Tristate::MAYBE, result);
736        Ok(())
737    }
738
739    #[test]
740    fn string_variant_truth() -> Result<(), Error> {
741        let result: bool = Variant::from("y").into();
742        assert_eq!(true, result);
743        let result: String = Variant::from("y").into();
744        assert_eq!("y".to_owned(), result);
745        let result: Tristate = Variant::from("y").into();
746        assert_eq!(Tristate::TRUE, result);
747        let result: i64 = Variant::from("y").into();
748        assert_eq!(1, result);
749        let result: Hex = Variant::from("y").into();
750        assert_eq!(Hex::from(1), result);
751
752        let result: bool = Variant::from("foo").into();
753        assert_eq!(false, result);
754        let result: String = Variant::from("foo").into();
755        assert_eq!("foo".to_owned(), result);
756        let result: Tristate = Variant::from("foo").into();
757        assert_eq!(Tristate::FALSE, result);
758        let result: i64 = Variant::from("foo").into();
759        assert_eq!(0, result);
760        let result: Hex = Variant::from("foo").into();
761        assert_eq!(Hex::from(0), result);
762        Ok(())
763    }
764
765    #[test]
766    fn tristate_variant_falsely() -> Result<(), Error> {
767        let result: bool = Variant::from(Tristate::FALSE).into();
768        assert_eq!(false, result);
769        let result: String = Variant::from(Tristate::FALSE).into();
770        assert_eq!("n".to_owned(), result);
771        let result: Tristate = Variant::from(Tristate::FALSE).into();
772        assert_eq!(Tristate::FALSE, result);
773        let result: i64 = Variant::from(Tristate::FALSE).into();
774        assert_eq!(0, result);
775        let result: Hex = Variant::from(Tristate::FALSE).into();
776        assert_eq!(Hex::from(0), result);
777        Ok(())
778    }
779
780    #[test]
781    fn tristate_variant_true() -> Result<(), Error> {
782        let result: bool = Variant::from(Tristate::TRUE).into();
783        assert_eq!(true, result);
784        let result: String = Variant::from(Tristate::TRUE).into();
785        assert_eq!("y".to_owned(), result);
786        let result: Tristate = Variant::from(Tristate::TRUE).into();
787        assert_eq!(Tristate::TRUE, result);
788        let result: i64 = Variant::from(Tristate::TRUE).into();
789        assert_eq!(1, result);
790        let result: Hex = Variant::from(Tristate::TRUE).into();
791        assert_eq!(Hex::from(1), result);
792
793        let result: bool = Variant::from(Tristate::MAYBE).into();
794        assert_eq!(true, result);
795        let result: String = Variant::from(Tristate::MAYBE).into();
796        assert_eq!("m".to_owned(), result);
797        let result: Tristate = Variant::from(Tristate::MAYBE).into();
798        assert_eq!(Tristate::MAYBE, result);
799        let result: i64 = Variant::from(Tristate::MAYBE).into();
800        assert_eq!(1, result);
801        let result: Hex = Variant::from(Tristate::MAYBE).into();
802        assert_eq!(Hex::from(1), result);
803        Ok(())
804    }
805
806    #[test]
807    fn int_variant_falsely() -> Result<(), Error> {
808        let result: bool = Variant::from(0).into();
809        assert_eq!(false, result);
810        let result: String = Variant::from(0).into();
811        assert_eq!("0".to_owned(), result);
812        let result: Tristate = Variant::from(0).into();
813        assert_eq!(Tristate::FALSE, result);
814        let result: i64 = Variant::from(0).into();
815        assert_eq!(0, result);
816        let result: Hex = Variant::from(0).into();
817        assert_eq!(Hex::from(0), result);
818        Ok(())
819    }
820
821    #[test]
822    fn int_variant_truth() -> Result<(), Error> {
823        for number in vec![1, 2, -1] {
824            let result: bool = Variant::from(number).into();
825            assert_eq!(true, result);
826            let result: String = Variant::from(number).into();
827            let s = number.to_string();
828            assert_eq!(s, result);
829            let result: Tristate = Variant::from(number).into();
830            assert_eq!(Tristate::TRUE, result);
831            let result: i64 = Variant::from(number).into();
832            assert_eq!(number, result);
833            let result: Hex = Variant::from(number).into();
834            if number > 0 {
835                assert_eq!(Hex::from(number as u64), result);
836            } else if number == -1 {
837                assert_eq!(Hex::from(0xffffffffffffffff), result);
838            }
839        }
840        Ok(())
841    }
842
843    #[test]
844    fn hex_variant_falsely() -> Result<(), Error> {
845        let number = Hex::from(0);
846        let result: bool = Variant::from(number).into();
847        assert_eq!(false, result);
848        let result: String = Variant::from(number).into();
849        assert_eq!("0x0".to_owned(), result);
850        let result: Tristate = Variant::from(number).into();
851        assert_eq!(Tristate::FALSE, result);
852        let result: i64 = Variant::from(number).into();
853        assert_eq!(0, result);
854        let result: Hex = Variant::from(number).into();
855        assert_eq!(Hex::from(0), result);
856        Ok(())
857    }
858
859    #[test]
860    fn hex_variant_truth() -> Result<(), Error> {
861        for number in vec![Hex::from(1), Hex::from(2), Hex::from(0xffffffffffffffff)] {
862            let result: bool = Variant::from(number).into();
863            assert_eq!(true, result);
864            let result: String = Variant::from(number).into();
865            let s = number.to_string();
866            assert_eq!(s, result);
867            let result: Tristate = Variant::from(number).into();
868            assert_eq!(Tristate::TRUE, result);
869            let result: i64 = Variant::from(number).into();
870            if number <= Hex::from(2) {
871                let value: u64 = number.into();
872                assert_eq!(value as i64, result);
873            } else if number == Hex::from(0xffffffffffffffff) {
874                assert_eq!(-1, result);
875            }
876            let result: Hex = Variant::from(number).into();
877            assert_eq!(number, result);
878        }
879        Ok(())
880    }
881
882    #[test]
883    fn datatype() -> Result<(), Error> {
884        assert_eq!(VariantDataType::Bool, Variant::from(false).datatype());
885        assert_eq!(VariantDataType::Bool, Variant::from(true).datatype());
886        assert_eq!(
887            VariantDataType::Tristate,
888            Variant::from(Tristate::FALSE).datatype()
889        );
890        assert_eq!(
891            VariantDataType::Tristate,
892            Variant::from(Tristate::TRUE).datatype()
893        );
894        assert_eq!(
895            VariantDataType::Tristate,
896            Variant::from(Tristate::MAYBE).datatype()
897        );
898        for number in vec![0, 1, 2, -1] {
899            assert_eq!(VariantDataType::Int, Variant::from(number).datatype());
900        }
901        for number in vec![Hex::from(1), Hex::from(2), Hex::from(0xffffffffffffffff)] {
902            assert_eq!(VariantDataType::Hex, Variant::from(number).datatype());
903        }
904        assert_eq!(VariantDataType::String, Variant::from("").datatype());
905        Ok(())
906    }
907
908    #[test]
909    fn new_types() -> Result<(), Error> {
910        assert_eq!(
911            "".to_owned(),
912            Variant::new_typed(&VariantDataType::String).to_string()
913        );
914        assert_eq!(false, Variant::new_typed(&VariantDataType::Bool).to_bool());
915        assert_eq!(
916            Tristate::FALSE,
917            Variant::new_typed(&VariantDataType::Tristate).to_tristate()
918        );
919        assert_eq!(0, Variant::new_typed(&VariantDataType::Int).to_int());
920        assert_eq!(
921            Hex::from(0),
922            Variant::new_typed(&VariantDataType::Hex).to_hex()
923        );
924        Ok(())
925    }
926
927    #[test]
928    fn to_hex() -> Result<(), Error> {
929        let value = Variant::from("123456789");
930        let result: i64 = value.into();
931        assert_eq!(123456789, result);
932
933        let value = Variant::from("-123456789");
935        let result: i64 = value.into();
936        assert_eq!(-123456789, result);
937
938        let value = Variant::from(" 123 456 789 ");
940        let result: i64 = value.into();
941        assert_eq!(123456789, result);
942
943        let value = Variant::from("_123_456_789_");
945        let result: i64 = value.into();
946        assert_eq!(123456789, result);
947
948        let value = Variant::from("0x123456789abcdef");
949        let result: Hex = value.into();
950        assert_eq!(Hex::from(0x123456789abcdef), result);
951
952        let value = Variant::from(" 0 x 1234 5678 9abc def0 ");
954        let result: Hex = value.into();
955        assert_eq!(Hex::from(0x123456789abcdef0), result);
956
957        let value = Variant::from("_0_x_1234_5678_9abc_def0_");
959        let result: Hex = value.into();
960        assert_eq!(Hex::from(0x123456789abcdef0), result);
961
962        Ok(())
963    }
964
965    #[test]
966    fn not() -> Result<(), Error> {
967        let value = Variant::from(true);
968        let inverse = !value;
969        assert_eq!(Variant::from(false), inverse);
970
971        let value = Variant::from(false);
972        let inverse = !value;
973        assert_eq!(Variant::from(true), inverse);
974
975        let value = Variant::from(Tristate::TRUE);
976        let inverse = !value;
977        assert_eq!(Variant::from(Tristate::FALSE), inverse);
978
979        let value = Variant::from(Tristate::MAYBE);
980        let inverse = !value;
981        assert_eq!(Variant::from(Tristate::MAYBE), inverse);
982
983        let value = Variant::from(Tristate::FALSE);
984        let inverse = !value;
985        assert_eq!(Variant::from(Tristate::TRUE), inverse);
986
987        Ok(())
988    }
989
990    #[test]
991    fn datatype_2_config_type() -> Result<(), Error> {
992        let config_type: ConfigType = VariantDataType::Bool.into();
993        assert_eq!(ConfigType::Bool, config_type);
994
995        let config_type: ConfigType = VariantDataType::Int.into();
996        assert_eq!(ConfigType::Int, config_type);
997
998        let config_type: ConfigType = VariantDataType::String.into();
999        assert_eq!(ConfigType::String, config_type);
1000
1001        let config_type: ConfigType = VariantDataType::Hex.into();
1002        assert_eq!(ConfigType::Hex, config_type);
1003
1004        let config_type: ConfigType = VariantDataType::Tristate.into();
1005        assert_eq!(ConfigType::Tristate, config_type);
1006
1007        Ok(())
1008    }
1009
1010    #[test]
1011    fn config_type_2_datatype() -> Result<(), Error> {
1012        let datatype = VariantDataType::from(&ConfigType::Bool);
1013        assert_eq!(VariantDataType::Bool, datatype);
1014
1015        let datatype = VariantDataType::from(&ConfigType::Tristate);
1016        assert_eq!(VariantDataType::Tristate, datatype);
1017
1018        let datatype = VariantDataType::from(&ConfigType::Hex);
1019        assert_eq!(VariantDataType::Hex, datatype);
1020
1021        let datatype = VariantDataType::from(&ConfigType::String);
1022        assert_eq!(VariantDataType::String, datatype);
1023
1024        let datatype = VariantDataType::from(&ConfigType::Int);
1025        assert_eq!(VariantDataType::Int, datatype);
1026
1027        Ok(())
1028    }
1029}