1use 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}