Skip to content

Commit 4573cbd

Browse files
committed
Merge branch 'master' into refactor-breaking-change
2 parents 11ee772 + 026b2ba commit 4573cbd

File tree

1 file changed

+65
-6
lines changed

1 file changed

+65
-6
lines changed

src/string.rs

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use alloc::{
22
borrow::{Cow},
33
boxed::Box,
44
rc::Rc,
5-
string::{String},
5+
string::String,
66
sync::Arc,
77
};
88
use core::{borrow::Borrow, hash::Hash, str::FromStr};
@@ -36,7 +36,7 @@ fn truncate_str(string: &str, max_len: usize) -> &str {
3636
}
3737
}
3838

39-
unreachable!("Len 0 is a char boundary")
39+
unreachable!("Len 0 is a char boundary");
4040
}
4141

4242
/// A fixed size String with length provided at creation denoted in [`ValidLength`], by default [`u32`].
@@ -62,10 +62,13 @@ impl<LenT: ValidLength> FixedString<LenT> {
6262
/// This method will not allocate, or copy the string data.
6363
///
6464
/// See [`Self::from_string_trunc`] for truncation behaviour.
65-
pub fn from_static_trunc(val: &'static str) -> Self {
66-
Self(FixedStringRepr::Static(StaticStr::from_static_str(
67-
truncate_str(val, LenT::MAX.to_usize()),
68-
)))
65+
pub fn from_static_trunc(mut val: &'static str) -> Self {
66+
let max_len = LenT::MAX.to_usize();
67+
if val.len() > max_len {
68+
val = truncate_str(val, max_len);
69+
}
70+
71+
Self(FixedStringRepr::Static(StaticStr::from_static_str(val)))
6972
}
7073

7174
/// Converts a string into a [`FixedString`], **truncating** if the value is larger than `LenT`'s maximum.
@@ -458,6 +461,29 @@ mod test {
458461
}
459462
}
460463

464+
// primarily intended to ensure no hangs occur
465+
#[cfg(any(target_pointer_width = "64", target_pointer_width = "32"))]
466+
fn check_u32_partial_roundtrip_generic(to_fixed: fn(String) -> FixedString<u32>) {
467+
for i in 0..=400u32 {
468+
let original = "a".repeat(i as usize);
469+
let fixed = to_fixed(original);
470+
471+
assert!(fixed.bytes().all(|c| c == b'a'));
472+
assert_eq!(fixed.len(), i);
473+
474+
if !fixed.is_static() {
475+
assert_eq!(fixed.is_inline(), fixed.len() <= 12);
476+
}
477+
}
478+
}
479+
480+
fn check_default_generic<LenT: ValidLength>() {
481+
let fixed = FixedString::<LenT>::default();
482+
483+
assert!(fixed.is_static());
484+
assert_eq!(fixed.as_str(), "");
485+
}
486+
461487
#[test]
462488
fn test_truncating_behaviour() {
463489
const STR: &str = "______________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________🦀";
@@ -502,6 +528,23 @@ mod test {
502528
});
503529
}
504530

531+
#[test]
532+
#[cfg(any(target_pointer_width = "64", target_pointer_width = "32"))]
533+
fn check_u32_partial_roundtrip() {
534+
check_u32_partial_roundtrip_generic(|original| {
535+
FixedString::<u32>::try_from(original).unwrap()
536+
});
537+
}
538+
539+
#[test]
540+
#[cfg(any(target_pointer_width = "64", target_pointer_width = "32"))]
541+
fn check_u32_partial_roundtrip_static() {
542+
check_u32_partial_roundtrip_generic(|original| {
543+
let static_str = Box::leak(original.into_boxed_str());
544+
FixedString::from_static_trunc(static_str)
545+
});
546+
}
547+
505548
#[test]
506549
#[cfg(feature = "serde")]
507550
fn check_u8_roundtrip_serde() {
@@ -524,6 +567,22 @@ mod test {
524567
});
525568
}
526569

570+
#[test]
571+
fn check_default_u8() {
572+
check_default_generic::<u8>();
573+
}
574+
575+
#[test]
576+
fn check_default_u16() {
577+
check_default_generic::<u16>();
578+
}
579+
580+
#[test]
581+
#[cfg(any(target_pointer_width = "64", target_pointer_width = "32"))]
582+
fn check_default_u32() {
583+
check_default_generic::<u32>();
584+
}
585+
527586
#[test]
528587
fn check_sizes() {
529588
type DoubleOpt<T> = Option<Option<T>>;

0 commit comments

Comments
 (0)