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