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}
33
34impl TryFrom<&ExprProperties> for FFI_ExprProperties {
35    type Error = DataFusionError;
36    fn try_from(value: &ExprProperties) -> Result<Self, Self::Error> {
37        let sort_properties = (&value.sort_properties).into();
38        let range = value.range.clone().try_into()?;
39
40        Ok(FFI_ExprProperties {
41            sort_properties,
42            range,
43            preserves_lex_ordering: value.preserves_lex_ordering,
44        })
45    }
46}
47
48impl TryFrom<FFI_ExprProperties> for ExprProperties {
49    type Error = DataFusionError;
50    fn try_from(value: FFI_ExprProperties) -> Result<Self, Self::Error> {
51        let sort_properties = (&value.sort_properties).into();
52        let range = value.range.try_into()?;
53        Ok(ExprProperties {
54            sort_properties,
55            range,
56            preserves_lex_ordering: value.preserves_lex_ordering,
57        })
58    }
59}
60
61#[repr(C)]
62#[derive(Debug)]
63pub enum FFI_SortProperties {
64    Ordered(FFI_SortOptions),
65    Unordered,
66    Singleton,
67}
68
69impl From<&SortProperties> for FFI_SortProperties {
70    fn from(value: &SortProperties) -> Self {
71        match value {
72            SortProperties::Unordered => FFI_SortProperties::Unordered,
73            SortProperties::Singleton => FFI_SortProperties::Singleton,
74            SortProperties::Ordered(o) => FFI_SortProperties::Ordered(o.into()),
75        }
76    }
77}
78
79impl From<&FFI_SortProperties> for SortProperties {
80    fn from(value: &FFI_SortProperties) -> Self {
81        match value {
82            FFI_SortProperties::Unordered => SortProperties::Unordered,
83            FFI_SortProperties::Singleton => SortProperties::Singleton,
84            FFI_SortProperties::Ordered(o) => SortProperties::Ordered(o.into()),
85        }
86    }
87}
88
89#[repr(C)]
90#[derive(Debug)]
91pub struct FFI_SortOptions {
92    pub descending: bool,
93    pub nulls_first: bool,
94}
95
96impl From<&SortOptions> for FFI_SortOptions {
97    fn from(value: &SortOptions) -> Self {
98        Self {
99            descending: value.descending,
100            nulls_first: value.nulls_first,
101        }
102    }
103}
104
105impl From<&FFI_SortOptions> for SortOptions {
106    fn from(value: &FFI_SortOptions) -> Self {
107        Self {
108            descending: value.descending,
109            nulls_first: value.nulls_first,
110        }
111    }
112}