Skip to content

Commit 6137e91

Browse files
authored
Add additional documentation and builder APIs to SortOptions (#6441)
* Minor: Add additional documentation and builder APIs to `SortOptions` * Port some uses * Update defaults * Add nulls_first() and nulls_last() and more examples
1 parent 62825b2 commit 6137e91

File tree

2 files changed

+118
-40
lines changed

2 files changed

+118
-40
lines changed

arrow-row/src/lib.rs

Lines changed: 10 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1492,10 +1492,7 @@ mod tests {
14921492

14931493
let converter = RowConverter::new(vec![SortField::new_with_options(
14941494
DataType::Boolean,
1495-
SortOptions {
1496-
descending: true,
1497-
nulls_first: false,
1498-
},
1495+
SortOptions::default().desc().with_nulls_first(false),
14991496
)])
15001497
.unwrap();
15011498

@@ -1613,10 +1610,7 @@ mod tests {
16131610

16141611
let converter = RowConverter::new(vec![SortField::new_with_options(
16151612
DataType::Binary,
1616-
SortOptions {
1617-
descending: true,
1618-
nulls_first: false,
1619-
},
1613+
SortOptions::default().desc().with_nulls_first(false),
16201614
)])
16211615
.unwrap();
16221616
let rows = converter.convert_columns(&[Arc::clone(&col)]).unwrap();
@@ -1695,10 +1689,7 @@ mod tests {
16951689

16961690
let converter = RowConverter::new(vec![SortField::new_with_options(
16971691
a.data_type().clone(),
1698-
SortOptions {
1699-
descending: true,
1700-
nulls_first: false,
1701-
},
1692+
SortOptions::default().desc().with_nulls_first(false),
17021693
)])
17031694
.unwrap();
17041695

@@ -1713,10 +1704,7 @@ mod tests {
17131704

17141705
let converter = RowConverter::new(vec![SortField::new_with_options(
17151706
a.data_type().clone(),
1716-
SortOptions {
1717-
descending: true,
1718-
nulls_first: true,
1719-
},
1707+
SortOptions::default().desc().with_nulls_first(true),
17201708
)])
17211709
.unwrap();
17221710

@@ -1889,10 +1877,7 @@ mod tests {
18891877
back[0].to_data().validate_full().unwrap();
18901878
assert_eq!(&back[0], &list);
18911879

1892-
let options = SortOptions {
1893-
descending: false,
1894-
nulls_first: false,
1895-
};
1880+
let options = SortOptions::default().asc().with_nulls_first(false);
18961881
let field = SortField::new_with_options(d.clone(), options);
18971882
let converter = RowConverter::new(vec![field]).unwrap();
18981883
let rows = converter.convert_columns(&[Arc::clone(&list)]).unwrap();
@@ -1909,10 +1894,7 @@ mod tests {
19091894
back[0].to_data().validate_full().unwrap();
19101895
assert_eq!(&back[0], &list);
19111896

1912-
let options = SortOptions {
1913-
descending: true,
1914-
nulls_first: false,
1915-
};
1897+
let options = SortOptions::default().desc().with_nulls_first(false);
19161898
let field = SortField::new_with_options(d.clone(), options);
19171899
let converter = RowConverter::new(vec![field]).unwrap();
19181900
let rows = converter.convert_columns(&[Arc::clone(&list)]).unwrap();
@@ -1929,10 +1911,7 @@ mod tests {
19291911
back[0].to_data().validate_full().unwrap();
19301912
assert_eq!(&back[0], &list);
19311913

1932-
let options = SortOptions {
1933-
descending: true,
1934-
nulls_first: true,
1935-
};
1914+
let options = SortOptions::default().desc().with_nulls_first(true);
19361915
let field = SortField::new_with_options(d, options);
19371916
let converter = RowConverter::new(vec![field]).unwrap();
19381917
let rows = converter.convert_columns(&[Arc::clone(&list)]).unwrap();
@@ -1992,10 +1971,7 @@ mod tests {
19921971
// null
19931972
// [[1, 2]]
19941973
// ]
1995-
let options = SortOptions {
1996-
descending: false,
1997-
nulls_first: true,
1998-
};
1974+
let options = SortOptions::default().asc().with_nulls_first(true);
19991975
let field = SortField::new_with_options(d.clone(), options);
20001976
let converter = RowConverter::new(vec![field]).unwrap();
20011977
let rows = converter.convert_columns(&[Arc::clone(&list)]).unwrap();
@@ -2011,10 +1987,7 @@ mod tests {
20111987
back[0].to_data().validate_full().unwrap();
20121988
assert_eq!(&back[0], &list);
20131989

2014-
let options = SortOptions {
2015-
descending: true,
2016-
nulls_first: true,
2017-
};
1990+
let options = SortOptions::default().desc().with_nulls_first(true);
20181991
let field = SortField::new_with_options(d.clone(), options);
20191992
let converter = RowConverter::new(vec![field]).unwrap();
20201993
let rows = converter.convert_columns(&[Arc::clone(&list)]).unwrap();
@@ -2030,10 +2003,7 @@ mod tests {
20302003
back[0].to_data().validate_full().unwrap();
20312004
assert_eq!(&back[0], &list);
20322005

2033-
let options = SortOptions {
2034-
descending: true,
2035-
nulls_first: false,
2036-
};
2006+
let options = SortOptions::default().desc().with_nulls_first(false);
20372007
let field = SortField::new_with_options(d, options);
20382008
let converter = RowConverter::new(vec![field]).unwrap();
20392009
let rows = converter.convert_columns(&[Arc::clone(&list)]).unwrap();

arrow-schema/src/lib.rs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
//! Arrow logical types
2020
2121
mod datatype;
22+
2223
pub use datatype::*;
24+
use std::fmt::Display;
2325
mod datatype_parse;
2426
mod error;
2527
pub use error::*;
@@ -35,6 +37,42 @@ use std::ops;
3537
pub mod ffi;
3638

3739
/// 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+
/// ```
3876
#[derive(Clone, Hash, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
3977
pub struct SortOptions {
4078
/// Whether to sort in descending order
@@ -43,6 +81,76 @@ pub struct SortOptions {
4381
pub nulls_first: bool,
4482
}
4583

84+
impl 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+
100+
impl 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+
46154
impl Default for SortOptions {
47155
fn default() -> Self {
48156
Self {

0 commit comments

Comments
 (0)