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}