donet_core/
dcarray.rs

1/*
2    This file is part of Donet.
3
4    Copyright © 2024 Max Rodriguez
5
6    Donet is free software; you can redistribute it and/or modify
7    it under the terms of the GNU Affero General Public License,
8    as published by the Free Software Foundation, either version 3
9    of the License, or (at your option) any later version.
10
11    Donet is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14    GNU Affero General Public License for more details.
15
16    You should have received a copy of the GNU Affero General Public
17    License along with Donet. If not, see <https://www.gnu.org/licenses/>.
18*/
19
20//! Data model of the DC Array element, which is a parameter
21//! type that stores a list of values of the same data type.
22
23use crate::dcnumeric::DCNumericRange;
24use crate::dctype::{DCNumber, DCTypeDefinition, DCTypeEnum};
25use crate::hashgen::*;
26
27pub struct DCArrayType {
28    base_type: Option<DCTypeDefinition>,
29    element_type: Option<DCTypeDefinition>,
30    array_size: u16,
31    array_range: Option<DCNumericRange>,
32}
33
34impl LegacyDCHash for DCArrayType {
35    fn generate_hash(&self, hashgen: &mut DCHashGenerator) {
36        self.base_type.clone().unwrap().generate_hash(hashgen);
37
38        if let Some(element_type) = self.element_type.clone() {
39            element_type.generate_hash(hashgen);
40        }
41        if self.has_range() {
42            hashgen.add_int(self.array_range.as_ref().unwrap().min.into())
43        } else {
44            hashgen.add_int(i32::from(self.array_size))
45        }
46    }
47}
48
49impl DCArrayType {
50    pub fn new(element_type: Option<DCTypeDefinition>, size: Option<DCNumericRange>) -> Self {
51        let mut new_array_type: Self = Self {
52            base_type: None,
53            element_type,
54            array_size: 0_u16,
55            array_range: size,
56        };
57
58        if new_array_type.array_range.is_none() {
59            new_array_type.array_range = None;
60            let range: &mut DCNumericRange = new_array_type.array_range.as_mut().unwrap();
61
62            range.min = DCNumber::UnsignedInteger(0_u64);
63            range.max = DCNumber::UnsignedInteger(u64::MAX);
64        } else {
65            let range: &mut DCNumericRange = new_array_type.array_range.as_mut().unwrap();
66
67            if range.min == range.max {
68                new_array_type.array_size = u64::from(range.min) as u16;
69            }
70        }
71
72        if new_array_type.element_type.is_some() {
73            let e_type: DCTypeDefinition = new_array_type.element_type.clone().unwrap();
74
75            let new_base_type: &mut DCTypeDefinition = new_array_type.base_type.as_mut().unwrap();
76
77            if !e_type.is_variable_length() && new_base_type.size > 0 {
78                new_base_type.data_type = DCTypeEnum::TArray;
79                new_base_type.size = new_array_type.array_size * e_type.get_size();
80            } else {
81                new_base_type.data_type = DCTypeEnum::TVarArray;
82                new_base_type.size = 0_u16;
83            }
84
85            match e_type.get_dc_type() {
86                DCTypeEnum::TChar => {
87                    if new_base_type.data_type == DCTypeEnum::TArray {
88                        new_base_type.data_type = DCTypeEnum::TString;
89                    } else {
90                        new_base_type.data_type = DCTypeEnum::TVarString;
91                    }
92                }
93                DCTypeEnum::TUInt8 => {
94                    if new_base_type.data_type == DCTypeEnum::TArray {
95                        new_base_type.data_type = DCTypeEnum::TBlob;
96                    } else {
97                        new_base_type.data_type = DCTypeEnum::TVarBlob;
98                    }
99                }
100                _ => {}
101            }
102        }
103        new_array_type
104    }
105
106    #[inline(always)]
107    pub fn get_array_size(&self) -> u16 {
108        self.base_type.clone().unwrap().size
109    }
110
111    #[inline(always)]
112    pub fn get_element_type(&self) -> Option<DCTypeDefinition> {
113        self.element_type.clone()
114    }
115
116    #[inline(always)]
117    pub fn get_range(&self) -> Option<DCNumericRange> {
118        self.array_range.clone()
119    }
120
121    #[inline(always)]
122    pub fn has_range(&self) -> bool {
123        self.array_range.is_some()
124    }
125}