Skip to content

Commit 48d2159

Browse files
authored
Merge pull request #580 from phip1611/uefi-str-rust-str-eq-improvements
Several small improvements to EqStrUntilNul
2 parents 4c4555c + 55179fd commit 48d2159

File tree

3 files changed

+58
-11
lines changed

3 files changed

+58
-11
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Changelog
22

33
## uefi - [Unreleased]
4+
- Implementations for the trait `EqStrUntilNul` now allow `?Sized` inputs. This means that
5+
you can write `some_cstr16.eq_str_until_nul("test")` instead of
6+
`some_cstr16.eq_str_until_nul(&"test")` now.
47

58
## uefi-macros - [Unreleased]
69

uefi/src/data_types/owned_strs.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ impl PartialEq<&CStr16> for CString16 {
128128
}
129129
}
130130

131-
impl<StrType: AsRef<str>> EqStrUntilNul<StrType> for CString16 {
131+
impl<StrType: AsRef<str> + ?Sized> EqStrUntilNul<StrType> for CString16 {
132132
fn eq_str_until_nul(&self, other: &StrType) -> bool {
133133
let this = self.as_ref();
134134
this.eq_str_until_nul(other)
@@ -190,12 +190,16 @@ mod tests {
190190
);
191191
}
192192

193-
/// Tests the trait implementation of trait [EqStrUntilNul].
193+
/// Tests the trait implementation of trait [`EqStrUntilNul]` for [`CString16`].
194+
///
195+
/// This tests that `String` and `str` from the standard library can be
196+
/// checked for equality against a [`CString16`]. It checks both directions,
197+
/// i.e., the equality is reflexive.
194198
#[test]
195199
fn test_cstring16_eq_std_str() {
196200
let input = CString16::try_from("test").unwrap();
197201

198-
// test various comparisons with different order (left, right)
202+
assert!(input.eq_str_until_nul("test")); // requires ?Sized constraint
199203
assert!(input.eq_str_until_nul(&"test"));
200204
assert!(input.eq_str_until_nul(&String::from("test")));
201205

uefi/src/data_types/strs.rs

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ impl fmt::Display for CStr8 {
136136
}
137137
}
138138

139-
impl<StrType: AsRef<str>> EqStrUntilNul<StrType> for CStr8 {
139+
impl<StrType: AsRef<str> + ?Sized> EqStrUntilNul<StrType> for CStr8 {
140140
fn eq_str_until_nul(&self, other: &StrType) -> bool {
141141
let other = other.as_ref();
142142

@@ -147,7 +147,8 @@ impl<StrType: AsRef<str>> EqStrUntilNul<StrType> for CStr8 {
147147
.copied()
148148
.map(char::from)
149149
.zip(other.chars())
150-
// this only works as CStr8 is guaranteed to have a fixed character length
150+
// This only works as CStr8 is guaranteed to have a fixed character length
151+
// (unlike UTF-8).
151152
.take_while(|(l, r)| *l != '\0' && *r != '\0')
152153
.any(|(l, r)| l != r);
153154

@@ -345,7 +346,7 @@ impl CStr16 {
345346
}
346347
}
347348

348-
impl<StrType: AsRef<str>> EqStrUntilNul<StrType> for CStr16 {
349+
impl<StrType: AsRef<str> + ?Sized> EqStrUntilNul<StrType> for CStr16 {
349350
fn eq_str_until_nul(&self, other: &StrType) -> bool {
350351
let other = other.as_ref();
351352

@@ -354,7 +355,8 @@ impl<StrType: AsRef<str>> EqStrUntilNul<StrType> for CStr16 {
354355
.copied()
355356
.map(char::from)
356357
.zip(other.chars())
357-
// this only works as CStr16 is guaranteed to have a fixed character length
358+
// This only works as CStr16 is guaranteed to have a fixed character length
359+
// (unlike UTF-8 or UTF-16).
358360
.take_while(|(l, r)| *l != '\0' && *r != '\0')
359361
.any(|(l, r)| l != r);
360362

@@ -416,10 +418,11 @@ impl<'a> UnalignedSlice<'a, u16> {
416418
}
417419
}
418420

419-
/// Trait that helps to compare Rust strings against CStr16 types.
420-
/// A generic implementation of this trait enables us that we only have to
421-
/// implement one direction (`left.eq_str_until_nul(&right)`) and we get
422-
/// the other direction (`right.eq_str_until_nul(&left)`) for free.
421+
/// The EqStrUntilNul trait helps to compare Rust strings against UEFI string types (UCS-2 strings).
422+
/// The given generic implementation of this trait enables us that we only have to
423+
/// implement one direction (`left.eq_str_until_nul(&right)`) for each UEFI string type and we
424+
/// get the other direction (`right.eq_str_until_nul(&left)`) for free. Hence, the relation is
425+
/// reflexive.
423426
pub trait EqStrUntilNul<StrType: ?Sized> {
424427
/// Checks if the provided Rust string `StrType` is equal to [Self] until the first null-byte
425428
/// is found. An exception is the terminating null-byte of [Self] which is ignored.
@@ -575,4 +578,41 @@ mod tests {
575578
const S: &CStr16 = cstr16!("ABC");
576579
assert_eq!(S.to_u16_slice_with_nul(), [65, 66, 67, 0]);
577580
}
581+
582+
/// Tests the trait implementation of trait [`EqStrUntilNul]` for [`CStr8`].
583+
///
584+
/// This tests that `String` and `str` from the standard library can be
585+
/// checked for equality against a [`CStr8`]. It checks both directions,
586+
/// i.e., the equality is reflexive.
587+
#[test]
588+
fn test_cstr8_eq_std_str() {
589+
let input: &CStr8 = cstr8!("test");
590+
591+
// test various comparisons with different order (left, right)
592+
assert!(input.eq_str_until_nul("test")); // requires ?Sized constraint
593+
assert!(input.eq_str_until_nul(&"test"));
594+
assert!(input.eq_str_until_nul(&String::from("test")));
595+
596+
// now other direction
597+
assert!(String::from("test").eq_str_until_nul(input));
598+
assert!("test".eq_str_until_nul(input));
599+
}
600+
601+
/// Tests the trait implementation of trait [`EqStrUntilNul]` for [`CStr16`].
602+
///
603+
/// This tests that `String` and `str` from the standard library can be
604+
/// checked for equality against a [`CStr16`]. It checks both directions,
605+
/// i.e., the equality is reflexive.
606+
#[test]
607+
fn test_cstr16_eq_std_str() {
608+
let input: &CStr16 = cstr16!("test");
609+
610+
assert!(input.eq_str_until_nul("test")); // requires ?Sized constraint
611+
assert!(input.eq_str_until_nul(&"test"));
612+
assert!(input.eq_str_until_nul(&String::from("test")));
613+
614+
// now other direction
615+
assert!(String::from("test").eq_str_until_nul(input));
616+
assert!("test".eq_str_until_nul(input));
617+
}
578618
}

0 commit comments

Comments
 (0)