1use std::time::Duration;
2
3use crate::model::*;
4
5#[derive(Copy, Clone, Debug, PartialEq, Eq)]
7pub struct StringType;
8
9#[non_exhaustive]
11#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd)]
12pub enum DurationType {
13    Milliseconds,
15    Seconds,
17}
18
19#[non_exhaustive]
21#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd)]
22pub enum DurationValue {
23    Milliseconds(u64),
25    Seconds(u64),
27}
28
29impl From<DurationValue> for DurationType {
30    fn from(x: DurationValue) -> Self {
31        match x {
32            DurationValue::Milliseconds(_) => DurationType::Milliseconds,
33            DurationValue::Seconds(_) => DurationType::Seconds,
34        }
35    }
36}
37
38impl DurationType {
39    pub fn unit(&self) -> &'static str {
40        match self {
41            DurationType::Milliseconds => "milliseconds",
42            DurationType::Seconds => "seconds",
43        }
44    }
45
46    pub fn get_value_string(&self, duration: Duration) -> String {
47        match self {
48            DurationType::Milliseconds => {
49                format!("{}", duration.as_millis())
50            }
51            DurationType::Seconds => {
52                format!("{}", duration.as_secs())
53            }
54        }
55    }
56}
57
58impl From<DurationType> for BasicType {
59    fn from(x: DurationType) -> Self {
60        BasicType::Duration(x)
61    }
62}
63
64#[derive(Debug, Clone)]
65pub struct Arg<T, D>
66where
67    T: Clone,
68    D: DocReference,
69{
70    pub(crate) arg_type: T,
71    pub(crate) name: Name,
72    pub(crate) doc: DocString<D>,
73}
74
75impl<T> Arg<T, Unvalidated>
76where
77    T: Clone,
78{
79    pub(crate) fn validate(&self, lib: &LibraryFields) -> BindResult<Arg<T, Validated>> {
80        Ok(Arg {
81            arg_type: self.arg_type.clone(),
82            name: self.name.clone(),
83            doc: self.doc.validate(&self.name, lib)?,
84        })
85    }
86}
87
88impl<T, D> Arg<T, D>
89where
90    T: Clone,
91    D: DocReference,
92{
93    pub(crate) fn new(arg_type: T, name: Name, doc: DocString<D>) -> Self {
94        Self {
95            arg_type,
96            name,
97            doc,
98        }
99    }
100}
101
102#[non_exhaustive]
104#[derive(Debug, Copy, Clone, PartialEq, Eq)]
105pub enum Primitive {
106    Bool,
107    U8,
108    S8,
109    U16,
110    S16,
111    U32,
112    S32,
113    U64,
114    S64,
115    Float,
116    Double,
117}
118
119#[non_exhaustive]
121#[derive(Debug, Copy, Clone)]
122pub enum PrimitiveValue {
123    Bool(bool),
124    U8(u8),
125    S8(i8),
126    U16(u16),
127    S16(i16),
128    U32(u32),
129    S32(i32),
130    U64(u64),
131    S64(i64),
132    Float(f32),
133    Double(f64),
134}
135
136impl From<PrimitiveValue> for Primitive {
137    fn from(x: PrimitiveValue) -> Self {
138        match x {
139            PrimitiveValue::Bool(_) => Primitive::Bool,
140            PrimitiveValue::U8(_) => Primitive::U8,
141            PrimitiveValue::S8(_) => Primitive::S8,
142            PrimitiveValue::U16(_) => Primitive::U16,
143            PrimitiveValue::S16(_) => Primitive::S16,
144            PrimitiveValue::U32(_) => Primitive::U32,
145            PrimitiveValue::S32(_) => Primitive::S32,
146            PrimitiveValue::U64(_) => Primitive::U64,
147            PrimitiveValue::S64(_) => Primitive::S64,
148            PrimitiveValue::Float(_) => Primitive::Float,
149            PrimitiveValue::Double(_) => Primitive::Double,
150        }
151    }
152}
153
154#[non_exhaustive]
157#[derive(Debug, Clone, PartialEq, Eq)]
158pub enum BasicType {
159    Primitive(Primitive),
160    Duration(DurationType),
161    Enum(Handle<Enum<Unvalidated>>),
162}
163
164impl From<Primitive> for BasicType {
165    fn from(x: Primitive) -> Self {
166        BasicType::Primitive(x)
167    }
168}
169
170impl InitializerValidator for Primitive {
171    fn validate_default_value(
172        &self,
173        value: &InitializerDefault,
174    ) -> BindResult<ValidatedDefaultValue> {
175        match self {
176            Self::U8 => match value {
177                InitializerDefault::Numeric(NumberValue::U8(x)) => Ok(NumberValue::U8(*x).into()),
178                _ => Err(BindingErrorVariant::StructInitializerBadValueForType {
179                    field_type: "u8".to_string(),
180                    value: value.clone(),
181                }
182                .into()),
183            },
184            Self::S8 => match value {
185                InitializerDefault::Numeric(NumberValue::S8(x)) => Ok(NumberValue::S8(*x).into()),
186                _ => Err(BindingErrorVariant::StructInitializerBadValueForType {
187                    field_type: "i8".to_string(),
188                    value: value.clone(),
189                }
190                .into()),
191            },
192            Self::U16 => match value {
193                InitializerDefault::Numeric(NumberValue::U16(x)) => Ok(NumberValue::U16(*x).into()),
194                _ => Err(BindingErrorVariant::StructInitializerBadValueForType {
195                    field_type: "u16".to_string(),
196                    value: value.clone(),
197                }
198                .into()),
199            },
200            Self::S16 => match value {
201                InitializerDefault::Numeric(NumberValue::S16(x)) => Ok(NumberValue::S16(*x).into()),
202                _ => Err(BindingErrorVariant::StructInitializerBadValueForType {
203                    field_type: "i16".to_string(),
204                    value: value.clone(),
205                }
206                .into()),
207            },
208            Self::U32 => match value {
209                InitializerDefault::Numeric(NumberValue::U32(x)) => Ok(NumberValue::U32(*x).into()),
210                _ => Err(BindingErrorVariant::StructInitializerBadValueForType {
211                    field_type: "u32".to_string(),
212                    value: value.clone(),
213                }
214                .into()),
215            },
216            Self::S32 => match value {
217                InitializerDefault::Numeric(NumberValue::S32(x)) => Ok(NumberValue::S32(*x).into()),
218                _ => Err(BindingErrorVariant::StructInitializerBadValueForType {
219                    field_type: "i32".to_string(),
220                    value: value.clone(),
221                }
222                .into()),
223            },
224            Self::U64 => match value {
225                InitializerDefault::Numeric(NumberValue::U64(x)) => Ok(NumberValue::U64(*x).into()),
226                _ => Err(BindingErrorVariant::StructInitializerBadValueForType {
227                    field_type: "u64".to_string(),
228                    value: value.clone(),
229                }
230                .into()),
231            },
232            Self::S64 => match value {
233                InitializerDefault::Numeric(NumberValue::S64(x)) => Ok(NumberValue::S64(*x).into()),
234                _ => Err(BindingErrorVariant::StructInitializerBadValueForType {
235                    field_type: "i64".to_string(),
236                    value: value.clone(),
237                }
238                .into()),
239            },
240            Self::Float => match value {
241                InitializerDefault::Numeric(NumberValue::Float(x)) => {
242                    Ok(NumberValue::Float(*x).into())
243                }
244                _ => Err(BindingErrorVariant::StructInitializerBadValueForType {
245                    field_type: "f32".to_string(),
246                    value: value.clone(),
247                }
248                .into()),
249            },
250            Self::Double => match value {
251                InitializerDefault::Numeric(NumberValue::Double(x)) => {
252                    Ok(NumberValue::Double(*x).into())
253                }
254                _ => Err(BindingErrorVariant::StructInitializerBadValueForType {
255                    field_type: "f64".to_string(),
256                    value: value.clone(),
257                }
258                .into()),
259            },
260            Primitive::Bool => match value {
261                InitializerDefault::Bool(x) => Ok(ValidatedDefaultValue::Bool(*x)),
262                _ => Err(BindingErrorVariant::StructInitializerBadValueForType {
263                    field_type: "bool".to_string(),
264                    value: value.clone(),
265                }
266                .into()),
267            },
268        }
269    }
270}
271
272impl InitializerValidator for BasicType {
273    fn validate_default_value(
274        &self,
275        value: &InitializerDefault,
276    ) -> BindResult<ValidatedDefaultValue> {
277        match self {
278            BasicType::Primitive(x) => x.validate_default_value(value),
279            BasicType::Duration(dt) => match value {
280                InitializerDefault::Duration(x) => Ok(ValidatedDefaultValue::Duration(*dt, *x)),
281                _ => Err(BindingErrorVariant::StructInitializerBadValueForType {
282                    field_type: "Duration".to_string(),
283                    value: value.clone(),
284                }
285                .into()),
286            },
287            BasicType::Enum(handle) => match value {
288                InitializerDefault::Enum(value) => {
289                    handle.validate_contains_variant_name(value)?;
290                    Ok(ValidatedDefaultValue::Enum(
291                        handle.clone(),
292                        Name::create(value)?,
293                    ))
294                }
295                _ => Err(BindingErrorVariant::StructInitializerBadValueForType {
296                    field_type: "Enum".to_string(),
297                    value: value.clone(),
298                }
299                .into()),
300            },
301        }
302    }
303}
304
305impl Primitive {
306    pub(crate) fn get_c_rust_type(&self) -> &str {
308        match self {
309            Self::Bool => "bool",
310            Self::U8 => "u8",
311            Self::S8 => "i8",
312            Self::U16 => "u16",
313            Self::S16 => "i16",
314            Self::U32 => "u32",
315            Self::S32 => "i32",
316            Self::U64 => "u64",
317            Self::S64 => "i64",
318            Self::Float => "f32",
319            Self::Double => "f64",
320        }
321    }
322}
323
324impl BasicType {
325    pub(crate) fn get_c_rust_type(&self) -> &str {
327        match self {
328            Self::Primitive(x) => x.get_c_rust_type(),
329            Self::Duration(_) => "u64",
330            Self::Enum(_) => "std::os::raw::c_int",
331        }
332    }
333}
334
335pub(crate) trait TypeExtractor {
336    fn get_basic_type(&self) -> Option<&BasicType>;
337
338    fn get_duration_type(&self) -> Option<DurationType> {
339        match self.get_basic_type() {
340            Some(BasicType::Duration(x)) => Some(*x),
341            _ => None,
342        }
343    }
344}
345
346impl TypeExtractor for FunctionArgStructField {
347    fn get_basic_type(&self) -> Option<&BasicType> {
348        match self {
349            Self::Basic(x) => Some(x),
350            _ => None,
351        }
352    }
353}
354
355impl TypeExtractor for FunctionReturnStructField {
356    fn get_basic_type(&self) -> Option<&BasicType> {
357        match self {
358            Self::Basic(x) => Some(x),
359            _ => None,
360        }
361    }
362}
363
364impl TypeExtractor for CallbackArgStructField {
365    fn get_basic_type(&self) -> Option<&BasicType> {
366        match self {
367            Self::Basic(x) => Some(x),
368            _ => None,
369        }
370    }
371}
372
373impl TypeExtractor for UniversalStructField {
374    fn get_basic_type(&self) -> Option<&BasicType> {
375        match self {
376            Self::Basic(x) => Some(x),
377            _ => None,
378        }
379    }
380}