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}