Skip to content

Commit ccd3801

Browse files
authored
Merge pull request #399 from newAM/string-from-utf8
String: add from_utf8
2 parents db324a3 + 4a300b5 commit ccd3801

File tree

2 files changed

+70
-1
lines changed

2 files changed

+70
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1515
- Implemented `retain` for `IndexMap` and `IndexSet`.
1616
- Recover `StableDeref` trait for `pool::object::Object` and `pool::boxed::Box`.
1717
- Add polyfills for ESP32S2
18+
- Added `String::from_utf8` and `String::from_utf8_unchecked`.
1819

1920
### Changed
2021

src/string.rs

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
use core::{cmp::Ordering, fmt, fmt::Write, hash, iter, ops, str};
1+
use core::{
2+
cmp::Ordering,
3+
fmt,
4+
fmt::Write,
5+
hash, iter, ops,
6+
str::{self, Utf8Error},
7+
};
28

39
use crate::Vec;
410

@@ -28,6 +34,68 @@ impl<const N: usize> String<N> {
2834
Self { vec: Vec::new() }
2935
}
3036

37+
/// Convert UTF-8 bytes into a `String`.
38+
///
39+
/// # Examples
40+
///
41+
/// Basic usage:
42+
///
43+
/// ```
44+
/// use heapless::{String, Vec};
45+
///
46+
/// let mut sparkle_heart = Vec::<u8, 4>::new();
47+
/// sparkle_heart.extend_from_slice(&[240, 159, 146, 150]);
48+
///
49+
/// let sparkle_heart: String<4> = String::from_utf8(sparkle_heart)?;
50+
/// assert_eq!("💖", sparkle_heart);
51+
/// # Ok::<(), core::str::Utf8Error>(())
52+
/// ```
53+
///
54+
/// Invalid UTF-8:
55+
///
56+
/// ```
57+
/// use core::str::Utf8Error;
58+
/// use heapless::{String, Vec};
59+
///
60+
/// let mut vec = Vec::<u8, 4>::new();
61+
/// vec.extend_from_slice(&[0, 159, 146, 150]);
62+
///
63+
/// let e: Utf8Error = String::from_utf8(vec).unwrap_err();
64+
/// assert_eq!(e.valid_up_to(), 1);
65+
/// # Ok::<(), core::str::Utf8Error>(())
66+
/// ```
67+
#[inline]
68+
pub fn from_utf8(vec: Vec<u8, N>) -> Result<Self, Utf8Error> {
69+
core::str::from_utf8(&vec)?;
70+
Ok(Self { vec })
71+
}
72+
73+
/// Convert UTF-8 bytes into a `String`, without checking that the string
74+
/// contains valid UTF-8.
75+
///
76+
/// # Safety
77+
///
78+
/// The bytes passed in must be valid UTF-8.
79+
///
80+
/// # Examples
81+
///
82+
/// Basic usage:
83+
///
84+
/// ```
85+
/// use heapless::{String, Vec};
86+
///
87+
/// let mut sparkle_heart = Vec::<u8, 4>::new();
88+
/// sparkle_heart.extend_from_slice(&[240, 159, 146, 150]);
89+
///
90+
/// // Safety: `sparkle_heart` Vec is known to contain valid UTF-8
91+
/// let sparkle_heart: String<4> = unsafe { String::from_utf8_unchecked(sparkle_heart) };
92+
/// assert_eq!("💖", sparkle_heart);
93+
/// ```
94+
#[inline]
95+
pub unsafe fn from_utf8_unchecked(vec: Vec<u8, N>) -> Self {
96+
Self { vec }
97+
}
98+
3199
/// Converts a `String` into a byte vector.
32100
///
33101
/// This consumes the `String`, so we do not need to copy its contents.

0 commit comments

Comments
 (0)