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