arrow_schema/lib.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
18//! Arrow logical types
19//!
20//! # Platform Support
21//!
22//! Only little-endian platforms are officially supported and tested in CI.
23//! Big-endian platforms are not tested in CI and may not work correctly.
24//! Fixes for big-endian platforms are welcome and handled on a best-effort basis,
25//! but compatibility is not guaranteed.
26
27#![doc(
28 html_logo_url = "https://arrow.apache.org/img/arrow-logo_chevrons_black-txt_white-bg.svg",
29 html_favicon_url = "https://arrow.apache.org/img/arrow-logo_chevrons_black-txt_transparent-bg.svg"
30)]
31#![cfg_attr(docsrs, feature(doc_cfg))]
32#![warn(missing_docs)]
33
34mod datatype;
35
36pub use datatype::*;
37use std::fmt::Display;
38mod datatype_display;
39mod datatype_parse;
40mod error;
41pub use error::*;
42pub mod extension;
43mod field;
44pub use field::*;
45mod fields;
46pub use fields::*;
47mod metadata;
48pub use metadata::*;
49mod schema;
50pub use schema::*;
51use std::ops;
52
53#[cfg(feature = "ffi")]
54pub mod ffi;
55
56/// Options that define the sort order of a given column
57///
58/// The default sorts equivalently to of `ASC NULLS FIRST` in SQL (i.e.
59/// ascending order with nulls sorting before any other values).
60///
61/// # Example creation
62/// ```
63/// # use arrow_schema::SortOptions;
64/// // configure using explicit initialization
65/// let options = SortOptions {
66/// descending: false,
67/// nulls_first: true,
68/// };
69/// // Default is ASC NULLs First
70/// assert_eq!(options, SortOptions::default());
71/// assert_eq!(options.to_string(), "ASC NULLS FIRST");
72///
73/// // Configure using builder APIs
74/// let options = SortOptions::default()
75/// .desc()
76/// .nulls_first();
77/// assert_eq!(options.to_string(), "DESC NULLS FIRST");
78///
79/// // configure using explicit field values
80/// let options = SortOptions::default()
81/// .with_descending(false)
82/// .with_nulls_first(false);
83/// assert_eq!(options.to_string(), "ASC NULLS LAST");
84/// ```
85///
86/// # Example operations
87/// It is also possible to negate the sort options using the `!` operator.
88/// ```
89/// use arrow_schema::SortOptions;
90/// let options = !SortOptions::default();
91/// assert_eq!(options.to_string(), "DESC NULLS LAST");
92/// ```
93#[derive(Clone, Hash, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
94pub struct SortOptions {
95 /// Whether to sort in descending order
96 pub descending: bool,
97 /// Whether to sort nulls first
98 pub nulls_first: bool,
99}
100
101impl Display for SortOptions {
102 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
103 if self.descending {
104 write!(f, "DESC")?;
105 } else {
106 write!(f, "ASC")?;
107 }
108 if self.nulls_first {
109 write!(f, " NULLS FIRST")?;
110 } else {
111 write!(f, " NULLS LAST")?;
112 }
113 Ok(())
114 }
115}
116
117impl SortOptions {
118 /// Create a new `SortOptions` struct
119 pub fn new(descending: bool, nulls_first: bool) -> Self {
120 Self {
121 descending,
122 nulls_first,
123 }
124 }
125
126 /// Set this sort options to sort in descending order
127 ///
128 /// See [Self::with_descending] to explicitly set the underlying field
129 pub fn desc(mut self) -> Self {
130 self.descending = true;
131 self
132 }
133
134 /// Set this sort options to sort in ascending order
135 ///
136 /// See [Self::with_descending] to explicitly set the underlying field
137 pub fn asc(mut self) -> Self {
138 self.descending = false;
139 self
140 }
141
142 /// Set this sort options to sort nulls first
143 ///
144 /// See [Self::with_nulls_first] to explicitly set the underlying field
145 pub fn nulls_first(mut self) -> Self {
146 self.nulls_first = true;
147 self
148 }
149
150 /// Set this sort options to sort nulls last
151 ///
152 /// See [Self::with_nulls_first] to explicitly set the underlying field
153 pub fn nulls_last(mut self) -> Self {
154 self.nulls_first = false;
155 self
156 }
157
158 /// Set this sort options to sort descending if argument is true
159 pub fn with_descending(mut self, descending: bool) -> Self {
160 self.descending = descending;
161 self
162 }
163
164 /// Set this sort options to sort nulls first if argument is true
165 pub fn with_nulls_first(mut self, nulls_first: bool) -> Self {
166 self.nulls_first = nulls_first;
167 self
168 }
169}
170
171impl Default for SortOptions {
172 fn default() -> Self {
173 Self {
174 descending: false,
175 // default to nulls first to match spark's behavior
176 nulls_first: true,
177 }
178 }
179}
180
181/// `!` operator is overloaded for `SortOptions` to invert boolean
182/// fields of the struct.
183impl ops::Not for SortOptions {
184 type Output = SortOptions;
185
186 fn not(self) -> SortOptions {
187 SortOptions {
188 descending: !self.descending,
189 nulls_first: !self.nulls_first,
190 }
191 }
192}
193
194#[test]
195fn test_overloaded_not_sort_options() {
196 let sort_options_array = [
197 SortOptions {
198 descending: false,
199 nulls_first: false,
200 },
201 SortOptions {
202 descending: false,
203 nulls_first: true,
204 },
205 SortOptions {
206 descending: true,
207 nulls_first: false,
208 },
209 SortOptions {
210 descending: true,
211 nulls_first: true,
212 },
213 ];
214
215 assert!((!sort_options_array[0]).descending);
216 assert!((!sort_options_array[0]).nulls_first);
217
218 assert!((!sort_options_array[1]).descending);
219 assert!(!(!sort_options_array[1]).nulls_first);
220
221 assert!(!(!sort_options_array[2]).descending);
222 assert!((!sort_options_array[2]).nulls_first);
223
224 assert!(!(!sort_options_array[3]).descending);
225 assert!(!(!sort_options_array[3]).nulls_first);
226}