it_lilo/lowerer/
lower_array.rs1use super::ILowerer;
18use super::LoResult;
19use crate::traits::Allocatable;
20use crate::utils::ser_value_size;
21use crate::utils::type_tag_form_ivalue;
22use crate::IValue;
23
24use it_memory_traits::MemoryView;
25
26pub struct LoweredArray {
27 pub offset: u32,
28 pub size: u32,
29}
30
31impl LoweredArray {
32 pub fn new(offset: u32, size: u32) -> Self {
33 Self { offset, size }
34 }
35
36 pub fn empty() -> Self {
37 Self { offset: 0, size: 0 }
38 }
39}
40
41#[async_recursion::async_recursion]
42pub async fn array_lower_memory<
43 A: Allocatable<MV, Store>,
44 MV: MemoryView<Store>,
45 Store: it_memory_traits::Store,
46>(
47 store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
48 lowerer: &mut ILowerer<'_, A, MV, Store>,
49 array_values: Vec<IValue>,
50) -> LoResult<LoweredArray> {
51 if array_values.is_empty() {
52 return Ok(LoweredArray::empty());
53 }
54
55 let elements_count = array_values.len() as u32;
56 let size = ser_value_size(&array_values[0]) * elements_count;
57 let type_tag = type_tag_form_ivalue(&array_values[0]);
58 let seq_writer = lowerer
59 .writer
60 .sequential_writer(store, size, type_tag)
61 .await?;
62
63 for value in array_values {
65 match value {
66 IValue::Boolean(value) => seq_writer.write_u8(store, &lowerer.writer, value as _),
67 IValue::S8(value) => seq_writer.write_u8(store, &lowerer.writer, value as _),
68 IValue::S16(value) => {
69 seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes())
70 }
71 IValue::S32(value) => {
72 seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes())
73 }
74 IValue::S64(value) => {
75 seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes())
76 }
77 IValue::U8(value) => {
78 seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes())
79 }
80 IValue::U16(value) => {
81 seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes())
82 }
83 IValue::U32(value) => {
84 seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes())
85 }
86 IValue::U64(value) => {
87 seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes())
88 }
89 IValue::I32(value) => {
90 seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes())
91 }
92 IValue::I64(value) => {
93 seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes())
94 }
95 IValue::F32(value) => {
96 seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes())
97 }
98 IValue::F64(value) => {
99 seq_writer.write_bytes(store, &lowerer.writer, &value.to_le_bytes())
100 }
101 IValue::String(value) => {
102 let offset = lowerer.writer.write_bytes(store, &value.as_bytes()).await? as u32;
103
104 seq_writer.write_bytes(store, &lowerer.writer, &offset.to_le_bytes());
105 seq_writer.write_bytes(store, &lowerer.writer, &(value.len() as u32).to_le_bytes());
106 }
107 IValue::ByteArray(values) => {
108 let offset = lowerer.writer.write_bytes(store, &values).await? as u32;
109
110 seq_writer.write_bytes(store, &lowerer.writer, &offset.to_le_bytes());
111 seq_writer.write_bytes(
112 store,
113 &lowerer.writer,
114 &(values.len() as u32).to_le_bytes(),
115 );
116 }
117 IValue::Array(values) => {
118 let LoweredArray { offset, size } =
119 array_lower_memory(store, lowerer, values).await?;
120
121 seq_writer.write_bytes(store, &lowerer.writer, &(offset as u32).to_le_bytes());
122 seq_writer.write_bytes(store, &lowerer.writer, &(size as u32).to_le_bytes());
123 }
124 IValue::Record(values) => {
125 let offset = super::record_lower_memory(store, lowerer, values).await? as u32;
126 seq_writer.write_bytes(store, &lowerer.writer, &offset.to_le_bytes());
127 }
128 }
129 }
130
131 let offset = seq_writer.start_offset();
132 let lowered_array = LoweredArray::new(offset, elements_count);
133 Ok(lowered_array)
134}