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}