forked from extern/nushell
Improve case insensitivity consistency (#10884)
# Description Add an extension trait `IgnoreCaseExt` to nu_utils which adds some case insensitivity helpers, and use them throughout nu to improve the handling of case insensitivity. Proper case folding is done via unicase, which is already a dependency via mime_guess from nu-command. In actuality a lot of code still does `to_lowercase`, because unicase only provides immediate comparison and doesn't expose a `to_folded_case` yet. And since we do a lot of `contains`/`starts_with`/`ends_with`, it's not sufficient to just have `eq_ignore_case`. But if we get access in the future, this makes us ready to use it with a change in one place. Plus, it's clearer what the purpose is at the call site to call `to_folded_case` instead of `to_lowercase` if it's exclusively for the purpose of case insensitive comparison, even if it just does `to_lowercase` still. # User-Facing Changes - Some commands that were supposed to be case insensitive remained only insensitive to ASCII case (a-z), and now are case insensitive w.r.t. non-ASCII characters as well. # Tests + Formatting - 🟢 `toolkit fmt` - 🟢 `toolkit clippy` - 🟢 `toolkit test` - 🟢 `toolkit test stdlib` --------- Co-authored-by: Stefan Holderbach <sholderbach@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
aed4b626b8
commit
0f600bc3f5
@ -1,6 +1,7 @@
|
||||
use alphanumeric_sort::compare_str;
|
||||
use nu_engine::column::nonexistent_column;
|
||||
use nu_protocol::{ShellError, Span, Value};
|
||||
use nu_utils::IgnoreCaseExt;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
// This module includes sorting functionality that is useful in sort-by and elsewhere.
|
||||
@ -125,28 +126,24 @@ pub fn sort(
|
||||
if insensitive {
|
||||
let span_a = a.span();
|
||||
let span_b = b.span();
|
||||
let lowercase_left = match a {
|
||||
Value::String { val, .. } => {
|
||||
Value::string(val.to_ascii_lowercase(), span_a)
|
||||
}
|
||||
let folded_left = match a {
|
||||
Value::String { val, .. } => Value::string(val.to_folded_case(), span_a),
|
||||
_ => a.clone(),
|
||||
};
|
||||
|
||||
let lowercase_right = match b {
|
||||
Value::String { val, .. } => {
|
||||
Value::string(val.to_ascii_lowercase(), span_b)
|
||||
}
|
||||
let folded_right = match b {
|
||||
Value::String { val, .. } => Value::string(val.to_folded_case(), span_b),
|
||||
_ => b.clone(),
|
||||
};
|
||||
|
||||
if natural {
|
||||
match (lowercase_left.as_string(), lowercase_right.as_string()) {
|
||||
match (folded_left.as_string(), folded_right.as_string()) {
|
||||
(Ok(left), Ok(right)) => compare_str(left, right),
|
||||
_ => Ordering::Equal,
|
||||
}
|
||||
} else {
|
||||
lowercase_left
|
||||
.partial_cmp(&lowercase_right)
|
||||
folded_left
|
||||
.partial_cmp(&folded_right)
|
||||
.unwrap_or(Ordering::Equal)
|
||||
}
|
||||
} else if natural {
|
||||
@ -189,23 +186,23 @@ pub fn compare(
|
||||
let result = if insensitive {
|
||||
let span_left = left_res.span();
|
||||
let span_right = right_res.span();
|
||||
let lowercase_left = match left_res {
|
||||
Value::String { val, .. } => Value::string(val.to_ascii_lowercase(), span_left),
|
||||
let folded_left = match left_res {
|
||||
Value::String { val, .. } => Value::string(val.to_folded_case(), span_left),
|
||||
_ => left_res,
|
||||
};
|
||||
|
||||
let lowercase_right = match right_res {
|
||||
Value::String { val, .. } => Value::string(val.to_ascii_lowercase(), span_right),
|
||||
let folded_right = match right_res {
|
||||
Value::String { val, .. } => Value::string(val.to_folded_case(), span_right),
|
||||
_ => right_res,
|
||||
};
|
||||
if natural {
|
||||
match (lowercase_left.as_string(), lowercase_right.as_string()) {
|
||||
match (folded_left.as_string(), folded_right.as_string()) {
|
||||
(Ok(left), Ok(right)) => compare_str(left, right),
|
||||
_ => Ordering::Equal,
|
||||
}
|
||||
} else {
|
||||
lowercase_left
|
||||
.partial_cmp(&lowercase_right)
|
||||
folded_left
|
||||
.partial_cmp(&folded_right)
|
||||
.unwrap_or(Ordering::Equal)
|
||||
}
|
||||
} else if natural {
|
||||
|
Reference in New Issue
Block a user