Skip to main content

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