rdf_fusion_encoding/sortable_term/
builder.rs

1use crate::sortable_term::encoding::{SortableTermEncoding, SortableTermEncodingField};
2use crate::sortable_term::term_type::SortableTermType;
3use datafusion::arrow::array::{
4    ArrayRef, BinaryBuilder, Float64Builder, StructBuilder, UInt8Builder,
5};
6use rdf_fusion_model::{BlankNodeRef, LiteralRef, NamedNodeRef};
7use rdf_fusion_model::{
8    Boolean, Date, DateTime, DayTimeDuration, Double, Duration, Integer, Numeric, Time,
9    YearMonthDuration,
10};
11use std::sync::Arc;
12
13pub struct SortableTermArrayBuilder {
14    builder: StructBuilder,
15}
16
17impl SortableTermArrayBuilder {
18    pub fn new(capacity: usize) -> Self {
19        Self {
20            builder: StructBuilder::from_fields(SortableTermEncoding::fields(), capacity),
21        }
22    }
23
24    pub fn append_null(&mut self) {
25        self.append(SortableTermType::Null, None, &[])
26    }
27
28    pub fn append_boolean(&mut self, value: Boolean) {
29        self.append(
30            SortableTermType::Boolean,
31            Some(value.into()),
32            &value.to_be_bytes(),
33        )
34    }
35
36    pub fn append_numeric(&mut self, value: Numeric, original_be_bytes: &[u8]) {
37        let value = Double::from(value);
38        self.append(SortableTermType::Numeric, Some(value), original_be_bytes)
39    }
40
41    pub fn append_blank_node(&mut self, value: BlankNodeRef<'_>) {
42        self.append(
43            SortableTermType::BlankNodes,
44            None,
45            value.as_str().as_bytes(),
46        )
47    }
48
49    pub fn append_named_node(&mut self, value: NamedNodeRef<'_>) {
50        self.append(SortableTermType::NamedNode, None, value.as_str().as_bytes())
51    }
52
53    pub fn append_string(&mut self, value: &str) {
54        self.append(SortableTermType::String, None, value.as_bytes())
55    }
56
57    pub fn append_date_time(&mut self, value: DateTime) {
58        self.append(
59            SortableTermType::DateTime,
60            Some(value.timestamp().value().into()),
61            &value.to_be_bytes(),
62        )
63    }
64
65    pub fn append_time(&mut self, value: Time) {
66        self.append(
67            SortableTermType::Time,
68            Some(value.timestamp().value().into()),
69            &value.to_be_bytes(),
70        )
71    }
72
73    pub fn append_date(&mut self, value: Date) {
74        self.append(
75            SortableTermType::Date,
76            Some(value.timestamp().value().into()),
77            &value.to_be_bytes(),
78        )
79    }
80
81    pub fn append_duration(&mut self, value: Duration) {
82        self.append(
83            SortableTermType::Duration,
84            None, // Sort by bytes
85            &value.to_be_bytes(),
86        )
87    }
88
89    pub fn append_year_month_duration(&mut self, value: YearMonthDuration) {
90        self.append(
91            SortableTermType::YearMonthDuration,
92            Some(Integer::from(value.as_i64()).into()),
93            Duration::from(value).to_be_bytes().as_slice(),
94        )
95    }
96
97    pub fn append_day_time_duration(&mut self, value: DayTimeDuration) {
98        self.append(
99            SortableTermType::DayTimeDuration,
100            Some(value.as_seconds().into()),
101            Duration::from(value).to_be_bytes().as_slice(),
102        )
103    }
104
105    pub fn append_literal(&mut self, literal: LiteralRef<'_>) {
106        self.append(
107            SortableTermType::UnsupportedLiteral,
108            None,
109            literal.value().as_bytes(),
110        )
111    }
112
113    fn append(
114        &mut self,
115        sort_type: SortableTermType,
116        numeric: Option<Double>,
117        bytes: &[u8],
118    ) {
119        self.builder
120            .field_builder::<UInt8Builder>(SortableTermEncodingField::Type.index())
121            .unwrap()
122            .append_value(sort_type.into());
123
124        let numeric_builder = self
125            .builder
126            .field_builder::<Float64Builder>(SortableTermEncodingField::Numeric.index())
127            .unwrap();
128        match numeric {
129            None => numeric_builder.append_null(),
130            Some(numeric) => numeric_builder.append_value(numeric.into()),
131        }
132
133        let bytes_builder = self
134            .builder
135            .field_builder::<BinaryBuilder>(SortableTermEncodingField::Bytes.index())
136            .unwrap();
137        bytes_builder.append_value(bytes);
138
139        self.builder.append(true)
140    }
141
142    pub fn finish(mut self) -> ArrayRef {
143        Arc::new(self.builder.finish())
144    }
145}