Skip to content

Commit 35e64a4

Browse files
jeckersbcgwalters
authored andcommitted
kernel_cmdline: impl PartialOrd/Ord/PartialEq/Eq for Parameter/ParameterKey
We need to be able to check equality on Cmdline by comparing sorted parameters. Signed-off-by: John Eckersberg <[email protected]>
1 parent 0334639 commit 35e64a4

File tree

1 file changed

+42
-17
lines changed

1 file changed

+42
-17
lines changed

crates/kernel_cmdline/src/bytes.rs

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//! arguments, supporting both key-only switches and key-value pairs with proper quote handling.
55
66
use std::borrow::Cow;
7+
use std::cmp::Ordering;
78
use std::ops::Deref;
89

910
use crate::{utf8, Action};
@@ -377,7 +378,7 @@ impl<'a, 'other> Extend<Parameter<'other>> for Cmdline<'a> {
377378
/// A single kernel command line parameter key
378379
///
379380
/// Handles quoted values and treats dashes and underscores in keys as equivalent.
380-
#[derive(Clone, Debug, Eq)]
381+
#[derive(Clone, Debug)]
381382
pub struct ParameterKey<'a>(pub(crate) &'a [u8]);
382383

383384
impl Deref for ParameterKey<'_> {
@@ -404,32 +405,42 @@ impl<'a, T: AsRef<[u8]> + ?Sized> From<&'a T> for ParameterKey<'a> {
404405
}
405406
}
406407

408+
impl ParameterKey<'_> {
409+
/// Returns an iterator over the canonicalized bytes of the
410+
/// parameter, with dashes turned into underscores.
411+
fn iter(&self) -> impl Iterator<Item = u8> + use<'_> {
412+
self.0
413+
.iter()
414+
.map(|&c: &u8| if c == b'-' { b'_' } else { c })
415+
}
416+
}
417+
407418
impl PartialEq for ParameterKey<'_> {
408419
/// Compares two parameter keys for equality.
409420
///
410421
/// Keys are compared with dashes and underscores treated as equivalent.
411422
/// This comparison is case-sensitive.
412423
fn eq(&self, other: &Self) -> bool {
413-
let dedashed = |&c: &u8| {
414-
if c == b'-' {
415-
b'_'
416-
} else {
417-
c
418-
}
419-
};
424+
self.iter().eq(other.iter())
425+
}
426+
}
427+
428+
impl Eq for ParameterKey<'_> {}
420429

421-
// We can't just zip() because leading substrings will match
422-
//
423-
// For example, "foo" == "foobar" since the zipped iterator
424-
// only compares the first three chars.
425-
let our_iter = self.0.iter().map(dedashed);
426-
let other_iter = other.0.iter().map(dedashed);
427-
our_iter.eq(other_iter)
430+
impl Ord for ParameterKey<'_> {
431+
fn cmp(&self, other: &Self) -> Ordering {
432+
self.iter().cmp(other.iter())
433+
}
434+
}
435+
436+
impl PartialOrd for ParameterKey<'_> {
437+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
438+
Some(self.cmp(other))
428439
}
429440
}
430441

431442
/// A single kernel command line parameter.
432-
#[derive(Clone, Debug, Eq)]
443+
#[derive(Clone, Debug)]
433444
pub struct Parameter<'a> {
434445
/// The full original value
435446
parameter: &'a [u8],
@@ -506,13 +517,27 @@ impl<'a> Parameter<'a> {
506517
}
507518
}
508519

509-
impl<'a> PartialEq for Parameter<'a> {
520+
impl PartialEq for Parameter<'_> {
510521
fn eq(&self, other: &Self) -> bool {
511522
// Note we don't compare parameter because we want hyphen-dash insensitivity for the key
512523
self.key == other.key && self.value == other.value
513524
}
514525
}
515526

527+
impl Eq for Parameter<'_> {}
528+
529+
impl Ord for Parameter<'_> {
530+
fn cmp(&self, other: &Self) -> Ordering {
531+
self.key.cmp(&other.key).then(self.value.cmp(&other.value))
532+
}
533+
}
534+
535+
impl PartialOrd for Parameter<'_> {
536+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
537+
Some(self.cmp(other))
538+
}
539+
}
540+
516541
impl Deref for Parameter<'_> {
517542
type Target = [u8];
518543

0 commit comments

Comments
 (0)