ifc_lite_server/services/
parquet_data_model_materials.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5use super::DataModelParquetError;
6use crate::services::data_model::MaterialAssociation;
7use arrow::array::{BooleanArray, Float64Array, StringArray, UInt32Array};
8use arrow::datatypes::{DataType, Field, Schema};
9use arrow::record_batch::RecordBatch;
10use std::sync::Arc;
11
12/// Serialize material associations table.
13pub(super) fn serialize_materials_table(
14    rows: &[MaterialAssociation],
15) -> Result<Vec<u8>, DataModelParquetError> {
16    let count = rows.len();
17    let mut element_ids = Vec::with_capacity(count);
18    let mut association_ids = Vec::with_capacity(count);
19    let mut definition_ids = Vec::with_capacity(count);
20    let mut member_counts = Vec::with_capacity(count);
21    let mut kinds = Vec::with_capacity(count);
22    let mut set_names: Vec<Option<String>> = Vec::with_capacity(count);
23    let mut layer_indices = Vec::with_capacity(count);
24    let mut material_names = Vec::with_capacity(count);
25    let mut material_name_presence = Vec::with_capacity(count);
26    let mut material_ids: Vec<Option<u32>> = Vec::with_capacity(count);
27    let mut member_names: Vec<Option<String>> = Vec::with_capacity(count);
28    let mut material_categories: Vec<Option<String>> = Vec::with_capacity(count);
29    let mut fractions: Vec<Option<f64>> = Vec::with_capacity(count);
30    let mut thicknesses: Vec<Option<f64>> = Vec::with_capacity(count);
31    let mut ventilated: Vec<Option<bool>> = Vec::with_capacity(count);
32    let mut categories: Vec<Option<String>> = Vec::with_capacity(count);
33
34    for row in rows {
35        element_ids.push(row.element_id);
36        association_ids.push(row.association_id);
37        definition_ids.push(row.definition_id);
38        member_counts.push(row.member_count);
39        kinds.push(row.kind.clone());
40        set_names.push(row.set_name.clone());
41        layer_indices.push(row.layer_index);
42        material_names.push(row.material_name.clone());
43        material_name_presence.push(row.material_name_present);
44        material_ids.push(row.material_id);
45        member_names.push(row.member_name.clone());
46        material_categories.push(row.material_category.clone());
47        fractions.push(row.fraction);
48        thicknesses.push(row.thickness);
49        ventilated.push(row.is_ventilated);
50        categories.push(row.category.clone());
51    }
52
53    let schema = Schema::new(vec![
54        Field::new("element_id", DataType::UInt32, false),
55        Field::new("set_name", DataType::Utf8, true),
56        Field::new("layer_index", DataType::UInt32, false),
57        Field::new("material_name", DataType::Utf8, false),
58        Field::new("material_name_present", DataType::Boolean, false),
59        Field::new("material_id", DataType::UInt32, true),
60        Field::new("thickness", DataType::Float64, true),
61        Field::new("is_ventilated", DataType::Boolean, true),
62        Field::new("category", DataType::Utf8, true),
63        Field::new("association_id", DataType::UInt32, false),
64        Field::new("definition_id", DataType::UInt32, false),
65        Field::new("member_count", DataType::UInt32, false),
66        Field::new("kind", DataType::Utf8, false),
67        Field::new("member_name", DataType::Utf8, true),
68        Field::new("material_category", DataType::Utf8, true),
69        Field::new("fraction", DataType::Float64, true),
70    ]);
71
72    let batch = RecordBatch::try_new(
73        Arc::new(schema),
74        vec![
75            Arc::new(UInt32Array::from(element_ids)),
76            Arc::new(StringArray::from(set_names)),
77            Arc::new(UInt32Array::from(layer_indices)),
78            Arc::new(StringArray::from(material_names)),
79            Arc::new(BooleanArray::from(material_name_presence)),
80            Arc::new(UInt32Array::from(material_ids)),
81            Arc::new(Float64Array::from(thicknesses)),
82            Arc::new(BooleanArray::from(ventilated)),
83            Arc::new(StringArray::from(categories)),
84            Arc::new(UInt32Array::from(association_ids)),
85            Arc::new(UInt32Array::from(definition_ids)),
86            Arc::new(UInt32Array::from(member_counts)),
87            Arc::new(StringArray::from(kinds)),
88            Arc::new(StringArray::from(member_names)),
89            Arc::new(StringArray::from(material_categories)),
90            Arc::new(Float64Array::from(fractions)),
91        ],
92    )?;
93
94    super::write_parquet_batch(batch)
95}