rust/kernel/str.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
These methods can be used to copy the data in a temporary c string into
a separate allocation, so that it can be accessed later even if the
original is deallocated.
The API in this change mirrors the standard library API for the `&str`
and `String` types. The `ToOwned` trait is not implemented because it
assumes that allocations are infallible.
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
---
rust/kernel/str.rs | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs
index b771310fa4a4..f3dc5b24ea55 100644
--- a/rust/kernel/str.rs
+++ b/rust/kernel/str.rs
@@ -2,6 +2,7 @@
//! String representations.
+use alloc::alloc::AllocError;
use alloc::vec::Vec;
use core::fmt::{self, Write};
use core::ops::{self, Deref, Index};
@@ -199,6 +200,12 @@ impl CStr {
pub unsafe fn as_str_unchecked(&self) -> &str {
unsafe { core::str::from_utf8_unchecked(self.as_bytes()) }
}
+
+ /// Convert this [`CStr`] into a [`CString`] by allocating memory and
+ /// copying over the string data.
+ pub fn to_cstring(&self) -> Result<CString, AllocError> {
+ CString::try_from(self)
+ }
}
impl fmt::Display for CStr {
@@ -584,6 +591,21 @@ impl Deref for CString {
}
}
+impl<'a> TryFrom<&'a CStr> for CString {
+ type Error = AllocError;
+
+ fn try_from(cstr: &'a CStr) -> Result<CString, AllocError> {
+ let mut buf = Vec::new();
+
+ buf.try_extend_from_slice(cstr.as_bytes_with_nul())
+ .map_err(|_| AllocError)?;
+
+ // INVARIANT: The `CStr` and `CString` types have the same invariants for
+ // the string data, and we copied it over without changes.
+ Ok(CString { buf })
+ }
+}
+
/// A convenience alias for [`core::format_args`].
#[macro_export]
macro_rules! fmt {
base-commit: ea76e08f4d901a450619831a255e9e0a4c0ed162
--
2.40.1.521.gf1e218fcd8-goog
On Wed, May 3, 2023 at 4:10 PM Alice Ryhl <aliceryhl@google.com> wrote: > > These methods can be used to copy the data in a temporary c string into > a separate allocation, so that it can be accessed later even if the > original is deallocated. > > The API in this change mirrors the standard library API for the `&str` > and `String` types. The `ToOwned` trait is not implemented because it > assumes that allocations are infallible. > > Reviewed-by: Benno Lossin <benno.lossin@proton.me> > Signed-off-by: Alice Ryhl <aliceryhl@google.com> Applied to `rust-next` -- thanks everyone! Cheers, Miguel
Alice Ryhl <aliceryhl@google.com> writes:
> These methods can be used to copy the data in a temporary c string into
> a separate allocation, so that it can be accessed later even if the
> original is deallocated.
>
> The API in this change mirrors the standard library API for the `&str`
> and `String` types. The `ToOwned` trait is not implemented because it
> assumes that allocations are infallible.
>
> Reviewed-by: Benno Lossin <benno.lossin@proton.me>
> Signed-off-by: Alice Ryhl <aliceryhl@google.com>
> ---
Reviewed-by: Andreas Hindborg <a.hindborg@samsung.com>
> rust/kernel/str.rs | 22 ++++++++++++++++++++++
> 1 file changed, 22 insertions(+)
>
> diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs
> index b771310fa4a4..f3dc5b24ea55 100644
> --- a/rust/kernel/str.rs
> +++ b/rust/kernel/str.rs
> @@ -2,6 +2,7 @@
>
> //! String representations.
>
> +use alloc::alloc::AllocError;
> use alloc::vec::Vec;
> use core::fmt::{self, Write};
> use core::ops::{self, Deref, Index};
> @@ -199,6 +200,12 @@ impl CStr {
> pub unsafe fn as_str_unchecked(&self) -> &str {
> unsafe { core::str::from_utf8_unchecked(self.as_bytes()) }
> }
> +
> + /// Convert this [`CStr`] into a [`CString`] by allocating memory and
> + /// copying over the string data.
> + pub fn to_cstring(&self) -> Result<CString, AllocError> {
> + CString::try_from(self)
> + }
> }
>
> impl fmt::Display for CStr {
> @@ -584,6 +591,21 @@ impl Deref for CString {
> }
> }
>
> +impl<'a> TryFrom<&'a CStr> for CString {
> + type Error = AllocError;
> +
> + fn try_from(cstr: &'a CStr) -> Result<CString, AllocError> {
> + let mut buf = Vec::new();
> +
> + buf.try_extend_from_slice(cstr.as_bytes_with_nul())
> + .map_err(|_| AllocError)?;
> +
> + // INVARIANT: The `CStr` and `CString` types have the same invariants for
> + // the string data, and we copied it over without changes.
> + Ok(CString { buf })
> + }
> +}
> +
> /// A convenience alias for [`core::format_args`].
> #[macro_export]
> macro_rules! fmt {
>
> base-commit: ea76e08f4d901a450619831a255e9e0a4c0ed162
On Wed, 3 May 2023 14:10:16 +0000
Alice Ryhl <aliceryhl@google.com> wrote:
> These methods can be used to copy the data in a temporary c string into
> a separate allocation, so that it can be accessed later even if the
> original is deallocated.
>
> The API in this change mirrors the standard library API for the `&str`
> and `String` types. The `ToOwned` trait is not implemented because it
> assumes that allocations are infallible.
How about add a `TryToOwned` trait to the kernel crate and implement
that trait for `CStr` instead?
Best,
Gary
>
> Reviewed-by: Benno Lossin <benno.lossin@proton.me>
> Signed-off-by: Alice Ryhl <aliceryhl@google.com>
> ---
> rust/kernel/str.rs | 22 ++++++++++++++++++++++
> 1 file changed, 22 insertions(+)
>
> diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs
> index b771310fa4a4..f3dc5b24ea55 100644
> --- a/rust/kernel/str.rs
> +++ b/rust/kernel/str.rs
> @@ -2,6 +2,7 @@
>
> //! String representations.
>
> +use alloc::alloc::AllocError;
> use alloc::vec::Vec;
> use core::fmt::{self, Write};
> use core::ops::{self, Deref, Index};
> @@ -199,6 +200,12 @@ impl CStr {
> pub unsafe fn as_str_unchecked(&self) -> &str {
> unsafe { core::str::from_utf8_unchecked(self.as_bytes()) }
> }
> +
> + /// Convert this [`CStr`] into a [`CString`] by allocating memory and
> + /// copying over the string data.
> + pub fn to_cstring(&self) -> Result<CString, AllocError> {
> + CString::try_from(self)
> + }
> }
>
> impl fmt::Display for CStr {
> @@ -584,6 +591,21 @@ impl Deref for CString {
> }
> }
>
> +impl<'a> TryFrom<&'a CStr> for CString {
> + type Error = AllocError;
> +
> + fn try_from(cstr: &'a CStr) -> Result<CString, AllocError> {
> + let mut buf = Vec::new();
> +
> + buf.try_extend_from_slice(cstr.as_bytes_with_nul())
> + .map_err(|_| AllocError)?;
> +
> + // INVARIANT: The `CStr` and `CString` types have the same invariants for
> + // the string data, and we copied it over without changes.
> + Ok(CString { buf })
> + }
> +}
> +
> /// A convenience alias for [`core::format_args`].
> #[macro_export]
> macro_rules! fmt {
>
> base-commit: ea76e08f4d901a450619831a255e9e0a4c0ed162
On 5/8/23 13:41, Gary Guo wrote: > On Wed, 3 May 2023 14:10:16 +0000 > Alice Ryhl <aliceryhl@google.com> wrote: > >> These methods can be used to copy the data in a temporary c string into >> a separate allocation, so that it can be accessed later even if the >> original is deallocated. >> >> The API in this change mirrors the standard library API for the `&str` >> and `String` types. The `ToOwned` trait is not implemented because it >> assumes that allocations are infallible. > > How about add a `TryToOwned` trait to the kernel crate and implement > that trait for `CStr` instead? Eh, I don't think it's worth it. It doesn't give anything new to the CStr api, and I think it's rather unlikely that someone will actually need to be generic over such a trait any time soon.
Alice Ryhl <alice@ryhl.io> writes: > On 5/8/23 13:41, Gary Guo wrote: >> On Wed, 3 May 2023 14:10:16 +0000 >> Alice Ryhl <aliceryhl@google.com> wrote: >> >>> These methods can be used to copy the data in a temporary c string into >>> a separate allocation, so that it can be accessed later even if the >>> original is deallocated. >>> >>> The API in this change mirrors the standard library API for the `&str` >>> and `String` types. The `ToOwned` trait is not implemented because it >>> assumes that allocations are infallible. >> How about add a `TryToOwned` trait to the kernel crate and implement >> that trait for `CStr` instead? > > Eh, I don't think it's worth it. It doesn't give anything new to the CStr api, > and I think it's rather unlikely that someone will actually need to be generic > over such a trait any time soon. It is just as valid as having `From<&str>` and `ToOwned<&str>`. While it does not add anything in terms of function, it carries intention. I think we should consider adding it at some point. BR Andreas
Andreas Hindborg <nmi@metaspace.dk> writes: > Alice Ryhl <alice@ryhl.io> writes: >> On 5/8/23 13:41, Gary Guo wrote: >>> On Wed, 3 May 2023 14:10:16 +0000 >>> Alice Ryhl <aliceryhl@google.com> wrote: >>>> These methods can be used to copy the data in a temporary c string into >>>> a separate allocation, so that it can be accessed later even if the >>>> original is deallocated. >>>> >>>> The API in this change mirrors the standard library API for the `&str` >>>> and `String` types. The `ToOwned` trait is not implemented because it >>>> assumes that allocations are infallible. >>> How about add a `TryToOwned` trait to the kernel crate and implement >>> that trait for `CStr` instead? >> >> Eh, I don't think it's worth it. It doesn't give anything new to the CStr api, >> and I think it's rather unlikely that someone will actually need to be generic >> over such a trait any time soon. > > It is just as valid as having `From<&str>` and `ToOwned<&str>`. While it > does not add anything in terms of function, it carries intention. I > think we should consider adding it at some point. > > BR Andreas Sure, I think its quite reasonable to add new traits, I just don't think it should be part of this patch. Adding new traits makes it a significantly bigger change IMO, and my changes have an actual user down the road. Alice
On Tue, 16 May 2023 11:12:02 +0000 Alice Ryhl <aliceryhl@google.com> wrote: > Andreas Hindborg <nmi@metaspace.dk> writes: > > Alice Ryhl <alice@ryhl.io> writes: > >> On 5/8/23 13:41, Gary Guo wrote: > >>> On Wed, 3 May 2023 14:10:16 +0000 > >>> Alice Ryhl <aliceryhl@google.com> wrote: > >>>> These methods can be used to copy the data in a temporary c string into > >>>> a separate allocation, so that it can be accessed later even if the > >>>> original is deallocated. > >>>> > >>>> The API in this change mirrors the standard library API for the `&str` > >>>> and `String` types. The `ToOwned` trait is not implemented because it > >>>> assumes that allocations are infallible. > >>> How about add a `TryToOwned` trait to the kernel crate and implement > >>> that trait for `CStr` instead? > >> > >> Eh, I don't think it's worth it. It doesn't give anything new to the CStr api, > >> and I think it's rather unlikely that someone will actually need to be generic > >> over such a trait any time soon. > > > > It is just as valid as having `From<&str>` and `ToOwned<&str>`. While it > > does not add anything in terms of function, it carries intention. I > > think we should consider adding it at some point. > > > > BR Andreas > > Sure, I think its quite reasonable to add new traits, I just don't think > it should be part of this patch. Adding new traits makes it a > significantly bigger change IMO, and my changes have an actual user down > the road. > > Alice Personally I think `CStr` to `CString` conversion should be implemented on top of `[u8]` to `Vec<u8>` conversion. Now we have two conversions that fit in the concept of `TryToOwned`, so a trait is warranted. Best, Gary
On 5/3/23 11:10, Alice Ryhl wrote:
> These methods can be used to copy the data in a temporary c string into
> a separate allocation, so that it can be accessed later even if the
> original is deallocated.
>
> The API in this change mirrors the standard library API for the `&str`
> and `String` types. The `ToOwned` trait is not implemented because it
> assumes that allocations are infallible.
>
> Reviewed-by: Benno Lossin <benno.lossin@proton.me>
> Signed-off-by: Alice Ryhl <aliceryhl@google.com>
> ---
> rust/kernel/str.rs | 22 ++++++++++++++++++++++
> 1 file changed, 22 insertions(+)
>
> diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs
> index b771310fa4a4..f3dc5b24ea55 100644
> --- a/rust/kernel/str.rs
> +++ b/rust/kernel/str.rs
> @@ -2,6 +2,7 @@
>
> //! String representations.
>
> +use alloc::alloc::AllocError;
> use alloc::vec::Vec;
> use core::fmt::{self, Write};
> use core::ops::{self, Deref, Index};
> @@ -199,6 +200,12 @@ impl CStr {
> pub unsafe fn as_str_unchecked(&self) -> &str {
> unsafe { core::str::from_utf8_unchecked(self.as_bytes()) }
> }
> +
> + /// Convert this [`CStr`] into a [`CString`] by allocating memory and
> + /// copying over the string data.
> + pub fn to_cstring(&self) -> Result<CString, AllocError> {
> + CString::try_from(self)
> + }
> }
>
> impl fmt::Display for CStr {
> @@ -584,6 +591,21 @@ impl Deref for CString {
> }
> }
>
> +impl<'a> TryFrom<&'a CStr> for CString {
> + type Error = AllocError;
> +
> + fn try_from(cstr: &'a CStr) -> Result<CString, AllocError> {
> + let mut buf = Vec::new();
> +
> + buf.try_extend_from_slice(cstr.as_bytes_with_nul())
> + .map_err(|_| AllocError)?;
> +
> + // INVARIANT: The `CStr` and `CString` types have the same invariants for
> + // the string data, and we copied it over without changes.
> + Ok(CString { buf })
> + }
> +}
> +
> /// A convenience alias for [`core::format_args`].
> #[macro_export]
> macro_rules! fmt {
>
> base-commit: ea76e08f4d901a450619831a255e9e0a4c0ed162
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
© 2016 - 2026 Red Hat, Inc.