Skip to main content

datafusion_ffi/expr/
expr_properties.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use arrow_schema::SortOptions;
19use datafusion_common::DataFusionError;
20use datafusion_expr::sort_properties::{ExprProperties, SortProperties};
21
22use crate::expr::interval::FFI_Interval;
23
24/// A stable struct for sharing [`ExprProperties`] across FFI boundaries.
25/// See [`ExprProperties`] for the meaning of each field.
26#[repr(C)]
27#[derive(Debug)]
28pub struct FFI_ExprProperties {
29    sort_properties: FFI_SortProperties,
30    range: FFI_Interval,
31    preserves_lex_ordering: bool,
32    strictly_order_preserving: bool,
33}
34
35impl TryFrom<&ExprProperties> for FFI_ExprProperties {
36    type Error = DataFusionError;
37    fn try_from(value: &ExprProperties) -> Result<Self, Self::Error> {
38        let sort_properties = (&value.sort_properties).into();
39        let range = value.range.clone().try_into()?;
40
41        Ok(FFI_ExprProperties {
42            sort_properties,
43            range,
44            preserves_lex_ordering: value.preserves_lex_ordering,
45            strictly_order_preserving: value.strictly_order_preserving,
46        })
47    }
48}
49
50impl TryFrom<FFI_ExprProperties> for ExprProperties {
51    type Error = DataFusionError;
52    fn try_from(value: FFI_ExprProperties) -> Result<Self, Self::Error> {
53        let sort_properties = (&value.sort_properties).into();
54        let range = value.range.try_into()?;
55        Ok(ExprProperties {
56            sort_properties,
57            range,
58            preserves_lex_ordering: value.preserves_lex_ordering,
59            strictly_order_preserving: value.strictly_order_preserving,
60        })
61    }
62}
63
64#[repr(C)]
65#[derive(Debug)]
66pub enum FFI_SortProperties {
67    Ordered(FFI_SortOptions),
68    Unordered,
69    Singleton,
70}
71
72impl From<&SortProperties> for FFI_SortProperties {
73    fn from(value: &SortProperties) -> Self {
74        match value {
75            SortProperties::Unordered => FFI_SortProperties::Unordered,
76            SortProperties::Singleton => FFI_SortProperties::Singleton,
77            SortProperties::Ordered(o) => FFI_SortProperties::Ordered(o.into()),
78        }
79    }
80}
81
82impl From<&FFI_SortProperties> for SortProperties {
83    fn from(value: &FFI_SortProperties) -> Self {
84        match value {
85            FFI_SortProperties::Unordered => SortProperties::Unordered,
86            FFI_SortProperties::Singleton => SortProperties::Singleton,
87            FFI_SortProperties::Ordered(o) => SortProperties::Ordered(o.into()),
88        }
89    }
90}
91
92#[repr(C)]
93#[derive(Debug)]
94pub struct FFI_SortOptions {
95    pub descending: bool,
96    pub nulls_first: bool,
97}
98
99impl From<&SortOptions> for FFI_SortOptions {
100    fn from(value: &SortOptions) -> Self {
101        Self {
102            descending: value.descending,
103            nulls_first: value.nulls_first,
104        }
105    }
106}
107
108impl From<&FFI_SortOptions> for SortOptions {
109    fn from(value: &FFI_SortOptions) -> Self {
110        Self {
111            descending: value.descending,
112            nulls_first: value.nulls_first,
113        }
114    }
115}