libmtp_rs/
values.rs

1//! This module contains items used to determine which values are allowed to
2//! be used on certain object attributes (aka properties).
3
4use libmtp_sys as ffi;
5use num_derive::FromPrimitive;
6use num_traits::FromPrimitive;
7
8/// Enumeration to determine the data type of the allowed values.
9#[derive(Debug, Clone, Copy, FromPrimitive)]
10pub enum DataType {
11    I8 = 0,
12    U8,
13    I16,
14    U16,
15    I32,
16    U32,
17    I64,
18    U64,
19}
20
21/// Contains relevant information about the allowed values for an specific type `T`.
22#[derive(Debug, Clone)]
23pub struct Values<T: Copy> {
24    max: T,
25    min: T,
26    step: T,
27    vals: Vec<T>,
28}
29
30impl<T: Copy> Values<T> {
31    pub fn max(&self) -> T {
32        self.max
33    }
34
35    pub fn min(&self) -> T {
36        self.min
37    }
38
39    pub fn step(&self) -> T {
40        self.step
41    }
42
43    pub fn vals(&self) -> &[T] {
44        &self.vals
45    }
46}
47
48/// Contains the allowed values of an specific attribute, determines which data type
49/// should be used, and if the values are a range or enumeration.
50#[derive(Debug, Clone)]
51pub struct AllowedValues {
52    u8_values: Option<Values<u8>>,
53    i8_values: Option<Values<i8>>,
54    u16_values: Option<Values<u16>>,
55    i16_values: Option<Values<i16>>,
56    u32_values: Option<Values<u32>>,
57    i32_values: Option<Values<i32>>,
58    u64_values: Option<Values<u64>>,
59    i64_values: Option<Values<i64>>,
60    datatype: DataType,
61    is_range: bool,
62}
63
64impl AllowedValues {
65    /// Check whether the allowed values are a range or enumeration.
66    pub fn is_range(&self) -> bool {
67        self.is_range
68    }
69
70    /// Returns the data type that should be used.
71    pub fn datatype(&self) -> DataType {
72        self.datatype
73    }
74
75    /// Returns the `u8` values, if the data type isn't `DataType::U8` this will
76    /// return `None`.
77    pub fn u8_values(&self) -> Option<&Values<u8>> {
78        self.u8_values.as_ref()
79    }
80
81    /// Returns the `i8` values, if the data type isn't `DataType::I8` this will
82    /// return `None`.
83    pub fn i8_values(&self) -> Option<&Values<i8>> {
84        self.i8_values.as_ref()
85    }
86
87    /// Returns the `u16` values, if the data type isn't `DataType::U16` this will
88    /// return `None`.
89    pub fn u16_values(&self) -> Option<&Values<u16>> {
90        self.u16_values.as_ref()
91    }
92
93    /// Returns the `i16` values, if the data type isn't `DataType::I16` this will
94    /// return `None`.
95    pub fn i16_values(&self) -> Option<&Values<i16>> {
96        self.i16_values.as_ref()
97    }
98
99    /// Returns the `u32` values, if the data type isn't `DataType::U32` this will
100    /// return `None`.
101    pub fn u32_values(&self) -> Option<&Values<u32>> {
102        self.u32_values.as_ref()
103    }
104
105    /// Returns the `i32` values, if the data type isn't `DataType::I32` this will
106    /// return `None`.
107    pub fn i32_values(&self) -> Option<&Values<i32>> {
108        self.i32_values.as_ref()
109    }
110
111    /// Returns the `u64` values, if the data type isn't `DataType::U64` this will
112    /// return `None`.
113    pub fn u64_values(&self) -> Option<&Values<u64>> {
114        self.u64_values.as_ref()
115    }
116
117    /// Returns the `i64` values, if the data type isn't `DataType::I64` this will
118    /// return `None`.
119    pub fn i64_values(&self) -> Option<&Values<i64>> {
120        self.i64_values.as_ref()
121    }
122}
123
124impl Default for AllowedValues {
125    fn default() -> Self {
126        AllowedValues {
127            u8_values: None,
128            i8_values: None,
129            u16_values: None,
130            i16_values: None,
131            u32_values: None,
132            i32_values: None,
133            u64_values: None,
134            i64_values: None,
135            datatype: DataType::I8,
136            is_range: false,
137        }
138    }
139}
140
141impl AllowedValues {
142    pub(crate) unsafe fn from_raw(raw: *mut ffi::LIBMTP_allowed_values_t) -> Option<Self> {
143        if raw.is_null() {
144            None
145        } else {
146            let len = (*raw).num_entries;
147            let datatype = DataType::from_u32((*raw).datatype).unwrap();
148            let is_range = (*raw).is_range != 0;
149
150            let base = Self::default();
151            let base = match datatype {
152                DataType::I8 => Self {
153                    datatype,
154                    is_range,
155                    i8_values: Some(Values {
156                        max: (*raw).i8max,
157                        min: (*raw).i8min,
158                        step: (*raw).i8step,
159                        vals: prim_array_ptr_to_vec!((*raw).i8vals, i8, len),
160                    }),
161                    ..base
162                },
163
164                DataType::U8 => Self {
165                    datatype,
166                    is_range,
167                    u8_values: Some(Values {
168                        max: (*raw).u8max,
169                        min: (*raw).u8min,
170                        step: (*raw).u8step,
171                        vals: prim_array_ptr_to_vec!((*raw).u8vals, u8, len),
172                    }),
173                    ..base
174                },
175
176                DataType::I16 => Self {
177                    datatype,
178                    is_range,
179                    i16_values: Some(Values {
180                        max: (*raw).i16max,
181                        min: (*raw).i16min,
182                        step: (*raw).i16step,
183                        vals: prim_array_ptr_to_vec!((*raw).i16vals, i16, len),
184                    }),
185                    ..base
186                },
187
188                DataType::U16 => Self {
189                    datatype,
190                    is_range,
191                    u16_values: Some(Values {
192                        max: (*raw).u16max,
193                        min: (*raw).u16min,
194                        step: (*raw).u16step,
195                        vals: prim_array_ptr_to_vec!((*raw).u16vals, u16, len),
196                    }),
197                    ..base
198                },
199
200                DataType::I32 => Self {
201                    datatype,
202                    is_range,
203                    i32_values: Some(Values {
204                        max: (*raw).i32max,
205                        min: (*raw).i32min,
206                        step: (*raw).i32step,
207                        vals: prim_array_ptr_to_vec!((*raw).i32vals, i32, len),
208                    }),
209                    ..base
210                },
211
212                DataType::U32 => Self {
213                    datatype,
214                    is_range,
215                    u32_values: Some(Values {
216                        max: (*raw).u32max,
217                        min: (*raw).u32min,
218                        step: (*raw).u32step,
219                        vals: prim_array_ptr_to_vec!((*raw).u32vals, u32, len),
220                    }),
221                    ..base
222                },
223
224                DataType::I64 => Self {
225                    datatype,
226                    is_range,
227                    i64_values: Some(Values {
228                        max: (*raw).i64max,
229                        min: (*raw).i64min,
230                        step: (*raw).i64step,
231                        vals: prim_array_ptr_to_vec!((*raw).i64vals, i64, len),
232                    }),
233                    ..base
234                },
235
236                DataType::U64 => Self {
237                    datatype,
238                    is_range,
239                    u64_values: Some(Values {
240                        max: (*raw).u64max,
241                        min: (*raw).u64min,
242                        step: (*raw).u64step,
243                        vals: prim_array_ptr_to_vec!((*raw).u64vals, u64, len),
244                    }),
245                    ..base
246                },
247            };
248
249            Some(base)
250        }
251    }
252}