Skip to main content

arrow_schema/
lib.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: See the NOTICE file distributed with this work for additional information regarding copyright ownership
3// SPDX-FileContributor: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements
4
5//! Arrow logical types
6//!
7//! # Platform Support
8//!
9//! Only little-endian platforms are officially supported and tested in CI.
10//! Big-endian platforms are not tested in CI and may not work correctly.
11//! Fixes for big-endian platforms are welcome and handled on a best-effort basis,
12//! but compatibility is not guaranteed.
13
14#![doc(
15    html_logo_url = "https://arrow.apache.org/img/arrow-logo_chevrons_black-txt_white-bg.svg",
16    html_favicon_url = "https://arrow.apache.org/img/arrow-logo_chevrons_black-txt_transparent-bg.svg"
17)]
18#![cfg_attr(docsrs, feature(doc_cfg))]
19#![warn(missing_docs)]
20
21mod datatype;
22
23pub use datatype::*;
24use std::fmt::Display;
25mod datatype_display;
26mod datatype_parse;
27mod error;
28pub use error::*;
29pub mod extension;
30mod field;
31pub use field::*;
32mod fields;
33pub use fields::*;
34mod metadata;
35pub use metadata::*;
36mod schema;
37pub use schema::*;
38use std::ops;
39
40#[cfg(feature = "ffi")]
41pub mod ffi;
42
43/// Options that define the sort order of a given column
44///
45/// The default sorts equivalently to of `ASC NULLS FIRST` in SQL (i.e.
46/// ascending order with nulls sorting before any other values).
47///
48/// # Example creation
49/// ```
50/// # use arrow_schema::SortOptions;
51/// // configure using explicit initialization
52/// let options = SortOptions {
53///   descending: false,
54///   nulls_first: true,
55/// };
56/// // Default is ASC NULLs First
57/// assert_eq!(options, SortOptions::default());
58/// assert_eq!(options.to_string(), "ASC NULLS FIRST");
59///
60/// // Configure using builder APIs
61/// let options = SortOptions::default()
62///  .desc()
63///  .nulls_first();
64/// assert_eq!(options.to_string(), "DESC NULLS FIRST");
65///
66/// // configure using explicit field values
67/// let options = SortOptions::default()
68///  .with_descending(false)
69///  .with_nulls_first(false);
70/// assert_eq!(options.to_string(), "ASC NULLS LAST");
71/// ```
72///
73/// # Example operations
74/// It is also possible to negate the sort options using the `!` operator.
75/// ```
76/// use arrow_schema::SortOptions;
77/// let options = !SortOptions::default();
78/// assert_eq!(options.to_string(), "DESC NULLS LAST");
79/// ```
80#[derive(Clone, Hash, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
81pub struct SortOptions {
82    /// Whether to sort in descending order
83    pub descending: bool,
84    /// Whether to sort nulls first
85    pub nulls_first: bool,
86}
87
88impl Display for SortOptions {
89    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
90        if self.descending {
91            write!(f, "DESC")?;
92        } else {
93            write!(f, "ASC")?;
94        }
95        if self.nulls_first {
96            write!(f, " NULLS FIRST")?;
97        } else {
98            write!(f, " NULLS LAST")?;
99        }
100        Ok(())
101    }
102}
103
104impl SortOptions {
105    /// Create a new `SortOptions` struct
106    pub fn new(descending: bool, nulls_first: bool) -> Self {
107        Self {
108            descending,
109            nulls_first,
110        }
111    }
112
113    /// Set this sort options to sort in descending order
114    ///
115    /// See [Self::with_descending] to explicitly set the underlying field
116    pub fn desc(mut self) -> Self {
117        self.descending = true;
118        self
119    }
120
121    /// Set this sort options to sort in ascending order
122    ///
123    /// See [Self::with_descending] to explicitly set the underlying field
124    pub fn asc(mut self) -> Self {
125        self.descending = false;
126        self
127    }
128
129    /// Set this sort options to sort nulls first
130    ///
131    /// See [Self::with_nulls_first] to explicitly set the underlying field
132    pub fn nulls_first(mut self) -> Self {
133        self.nulls_first = true;
134        self
135    }
136
137    /// Set this sort options to sort nulls last
138    ///
139    /// See [Self::with_nulls_first] to explicitly set the underlying field
140    pub fn nulls_last(mut self) -> Self {
141        self.nulls_first = false;
142        self
143    }
144
145    /// Set this sort options to sort descending if argument is true
146    pub fn with_descending(mut self, descending: bool) -> Self {
147        self.descending = descending;
148        self
149    }
150
151    /// Set this sort options to sort nulls first if argument is true
152    pub fn with_nulls_first(mut self, nulls_first: bool) -> Self {
153        self.nulls_first = nulls_first;
154        self
155    }
156}
157
158impl Default for SortOptions {
159    fn default() -> Self {
160        Self {
161            descending: false,
162            // default to nulls first to match spark's behavior
163            nulls_first: true,
164        }
165    }
166}
167
168/// `!` operator is overloaded for `SortOptions` to invert boolean
169/// fields of the struct.
170impl ops::Not for SortOptions {
171    type Output = SortOptions;
172
173    fn not(self) -> SortOptions {
174        SortOptions {
175            descending: !self.descending,
176            nulls_first: !self.nulls_first,
177        }
178    }
179}
180
181#[test]
182fn test_overloaded_not_sort_options() {
183    let sort_options_array = [
184        SortOptions {
185            descending: false,
186            nulls_first: false,
187        },
188        SortOptions {
189            descending: false,
190            nulls_first: true,
191        },
192        SortOptions {
193            descending: true,
194            nulls_first: false,
195        },
196        SortOptions {
197            descending: true,
198            nulls_first: true,
199        },
200    ];
201
202    assert!((!sort_options_array[0]).descending);
203    assert!((!sort_options_array[0]).nulls_first);
204
205    assert!((!sort_options_array[1]).descending);
206    assert!(!(!sort_options_array[1]).nulls_first);
207
208    assert!(!(!sort_options_array[2]).descending);
209    assert!((!sort_options_array[2]).nulls_first);
210
211    assert!(!(!sort_options_array[3]).descending);
212    assert!(!(!sort_options_array[3]).nulls_first);
213}