dbase/field/
conversion.rs1use super::{types, FieldType, FieldValue};
2
3#[derive(Debug)]
6pub enum FieldConversionError {
7 FieldTypeNotAsExpected {
10 expected: FieldType,
12 actual: FieldType,
14 },
15 IncompatibleType,
16 NoneValue,
19}
20
21impl std::fmt::Display for FieldConversionError {
22 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23 match self {
24 FieldConversionError::FieldTypeNotAsExpected { expected, actual } => {
25 write!(f, "Cannot convert from {} to {}", expected, actual)
26 }
27 FieldConversionError::IncompatibleType => write!(f, "The type is not compatible"),
28 FieldConversionError::NoneValue => {
29 write!(f, "Value is not initialized, which is not allowed")
30 }
31 }
32 }
33}
34
35impl std::error::Error for FieldConversionError {}
36
37macro_rules! impl_try_from_field_value_for_ {
38 (FieldValue::$variant:ident => $out_type:ty) => {
39 impl TryFrom<FieldValue> for $out_type {
40 type Error = FieldConversionError;
41
42 fn try_from(value: FieldValue) -> Result<Self, Self::Error> {
43 if let FieldValue::$variant(v) = value {
44 Ok(v)
45 } else {
46 Err(FieldConversionError::FieldTypeNotAsExpected {
47 expected: FieldType::$variant,
48 actual: value.field_type(),
49 })
50 }
51 }
52 }
53 };
54 (FieldValue::$variant:ident(Some($v:ident)) => $out_type:ty) => {
55 impl TryFrom<FieldValue> for $out_type {
56 type Error = FieldConversionError;
57
58 fn try_from(value: FieldValue) -> Result<Self, Self::Error> {
59 match value {
60 FieldValue::$variant(Some($v)) => Ok($v),
61 FieldValue::$variant(None) => Err(FieldConversionError::NoneValue),
62 _ => Err(FieldConversionError::FieldTypeNotAsExpected {
63 expected: FieldType::$variant,
64 actual: value.field_type(),
65 }),
66 }
67 }
68 }
69 };
70}
71
72impl_try_from_field_value_for_!(FieldValue::Numeric => Option<f64>);
73
74impl_try_from_field_value_for_!(FieldValue::Float => Option<f32>);
75impl_try_from_field_value_for_!(FieldValue::Float(Some(v)) => f32);
76
77impl_try_from_field_value_for_!(FieldValue::Date => Option<types::Date>);
78impl_try_from_field_value_for_!(FieldValue::Date(Some(v)) => types::Date);
79
80impl_try_from_field_value_for_!(FieldValue::Character => Option<String>);
81impl_try_from_field_value_for_!(FieldValue::Character(Some(string)) => String);
82
83impl_try_from_field_value_for_!(FieldValue::Logical => Option<bool>);
84impl_try_from_field_value_for_!(FieldValue::Logical(Some(b)) => bool);
85
86impl_try_from_field_value_for_!(FieldValue::Integer => i32);
87
88impl TryFrom<FieldValue> for f64 {
89 type Error = FieldConversionError;
90
91 fn try_from(value: FieldValue) -> Result<Self, Self::Error> {
92 match value {
93 FieldValue::Numeric(Some(v)) => Ok(v),
94 FieldValue::Numeric(None) => Err(FieldConversionError::NoneValue),
95 FieldValue::Currency(c) => Ok(c),
96 FieldValue::Double(d) => Ok(d),
97 _ => Err(FieldConversionError::IncompatibleType),
98 }
99 }
100}
101
102impl_try_from_field_value_for_!(FieldValue::DateTime => types::DateTime);
104
105macro_rules! impl_from_type_for_field_value (
106 ($t:ty => FieldValue::$variant:ident) => {
107 impl From<$t> for FieldValue {
108 fn from(v: $t) -> Self {
109 FieldValue::$variant(v)
110 }
111 }
112 };
113 ($t:ty => FieldValue::$variant:ident(Some($v:ident))) => {
114 impl From<$t> for FieldValue {
115 fn from(v: $t) -> Self {
116 FieldValue::$variant(Some(v))
117 }
118 }
119 }
120);
121
122impl_from_type_for_field_value!(Option<String> => FieldValue::Character);
123impl_from_type_for_field_value!(String => FieldValue::Character(Some(s)));
124
125impl_from_type_for_field_value!(Option<f64> => FieldValue::Numeric);
126impl_from_type_for_field_value!(f64 => FieldValue::Numeric(Some(v)));
127
128impl_from_type_for_field_value!(Option<f32> => FieldValue::Float);
129impl_from_type_for_field_value!(f32 => FieldValue::Float(Some(v)));
130
131impl_from_type_for_field_value!(Option<bool> => FieldValue::Logical);
132impl_from_type_for_field_value!(bool => FieldValue::Logical(Some(v)));
133
134impl_from_type_for_field_value!(Option<types::Date> => FieldValue::Date);
135impl_from_type_for_field_value!(types::Date => FieldValue::Date(Some(v)));
136
137impl_from_type_for_field_value!(types::DateTime => FieldValue::DateTime);