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