Coverage Report

Created: 2025-08-26 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/Users/andrewlamb/Software/arrow-rs/arrow-schema/src/lib.rs
Line
Count
Source
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
27
mod datatype;
28
29
pub use datatype::*;
30
use std::fmt::Display;
31
mod datatype_parse;
32
mod error;
33
pub use error::*;
34
pub mod extension;
35
mod field;
36
pub use field::*;
37
mod fields;
38
pub use fields::*;
39
mod schema;
40
pub use schema::*;
41
use std::ops;
42
43
#[cfg(feature = "ffi")]
44
pub 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)]
84
pub 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
91
impl Display for SortOptions {
92
0
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
93
0
        if self.descending {
94
0
            write!(f, "DESC")?;
95
        } else {
96
0
            write!(f, "ASC")?;
97
        }
98
0
        if self.nulls_first {
99
0
            write!(f, " NULLS FIRST")?;
100
        } else {
101
0
            write!(f, " NULLS LAST")?;
102
        }
103
0
        Ok(())
104
0
    }
105
}
106
107
impl SortOptions {
108
    /// Create a new `SortOptions` struct
109
0
    pub fn new(descending: bool, nulls_first: bool) -> Self {
110
0
        Self {
111
0
            descending,
112
0
            nulls_first,
113
0
        }
114
0
    }
115
116
    /// Set this sort options to sort in descending order
117
    ///
118
    /// See [Self::with_descending] to explicitly set the underlying field
119
0
    pub fn desc(mut self) -> Self {
120
0
        self.descending = true;
121
0
        self
122
0
    }
123
124
    /// Set this sort options to sort in ascending order
125
    ///
126
    /// See [Self::with_descending] to explicitly set the underlying field
127
0
    pub fn asc(mut self) -> Self {
128
0
        self.descending = false;
129
0
        self
130
0
    }
131
132
    /// Set this sort options to sort nulls first
133
    ///
134
    /// See [Self::with_nulls_first] to explicitly set the underlying field
135
0
    pub fn nulls_first(mut self) -> Self {
136
0
        self.nulls_first = true;
137
0
        self
138
0
    }
139
140
    /// Set this sort options to sort nulls last
141
    ///
142
    /// See [Self::with_nulls_first] to explicitly set the underlying field
143
0
    pub fn nulls_last(mut self) -> Self {
144
0
        self.nulls_first = false;
145
0
        self
146
0
    }
147
148
    /// Set this sort options to sort descending if argument is true
149
0
    pub fn with_descending(mut self, descending: bool) -> Self {
150
0
        self.descending = descending;
151
0
        self
152
0
    }
153
154
    /// Set this sort options to sort nulls first if argument is true
155
0
    pub fn with_nulls_first(mut self, nulls_first: bool) -> Self {
156
0
        self.nulls_first = nulls_first;
157
0
        self
158
0
    }
159
}
160
161
impl Default for SortOptions {
162
0
    fn default() -> Self {
163
0
        Self {
164
0
            descending: false,
165
0
            // default to nulls first to match spark's behavior
166
0
            nulls_first: true,
167
0
        }
168
0
    }
169
}
170
171
/// `!` operator is overloaded for `SortOptions` to invert boolean
172
/// fields of the struct.
173
impl ops::Not for SortOptions {
174
    type Output = SortOptions;
175
176
0
    fn not(self) -> SortOptions {
177
0
        SortOptions {
178
0
            descending: !self.descending,
179
0
            nulls_first: !self.nulls_first,
180
0
        }
181
0
    }
182
}
183
184
#[test]
185
fn 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
}