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