# CStr API extensions

**URL:** <https://internals.rust-lang.org/t/cstr-api-extensions/21832>\
**Category:** libs\
**Created:** [November 6, 2024, 3:39pm UTC](https://internals.rust-lang.org/t/cstr-api-extensions/21832 "2024-11-06T15:39:09Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![CodesInChaos](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/codesinchaos/32/5211_2.png) [@CodesInChaos](https://internals.rust-lang.org/u/CodesInChaos)\
**Post date:** [November 6, 2024, 3:39pm UTC](https://internals.rust-lang.org/t/cstr-api-extensions/21832/1 "2024-11-06T15:39:09Z")

</div>

I'm proposing two groups of enhancements to CStr:

1. Ability to convert a `c_char` pointer to a `CStr` pointer. This is useful to create an owning wrapper type around a `CStr` allocated by a C library. This could even be a generic `LibcBox<CStr>`, which only needs to care about `CStr` in a constructor method.

2. Enable accessing a `CStr` as a `[NonZero<u8>]`

---

<div class="post-metadata">

**Author:** ![CodesInChaos](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/codesinchaos/32/5211_2.png) [@CodesInChaos](https://internals.rust-lang.org/u/CodesInChaos)\
**Post date:** [July 11, 2025, 1:42pm UTC](https://internals.rust-lang.org/t/cstr-api-extensions/21832/2 "2025-07-11T13:42:19Z")

</div>

```rust
impl AsRef<[NonZero<u8>]> for CStr;
impl AsMut<[NonZero<u8>]> for CStr;

```

Probably should use `From<&CStr>`/`From<&mut CStr>` instead of `AsRef`/`AsMut`, since these will have O(n) runtime if/when the length field is removed form `CStr`, and `AsRef` is supposed to be fast.

> If you need to do a costly conversion it is better to implement [`From`](https://doc.rust-lang.org/std/convert/trait.From.html) with type `&T` or write a custom function.

* * *

Conversion from `Vec<NonZero<u8>>` would be useful for constructing a `CString`. In particular `From<Vec<NonZero<u8>>` would be infallible and thus could skip validation and error handling.

Currently the recommended way for constructing a `CString` is the fallible conversion from `Vec<u8>`.

```
// never allocates
impl From<CString> for Vec<NonZero<u8>>;

// needs to add a zero terminator, so it can allocate, but often will not
impl From<Vec<NonZero<u8>>> for CString;

```

* * *

Is removing the length field only planned for `&CStr` by making it truly unsized instead of dynamically sized, or is an analogous change removing the length field planned for `CString` as well?

If yes, the concatenation functions I proposed might not be such a great idea, since repeated concatenation will have the well known O(n^2) performance pitfall from determining the length of left side.

* * *

Slicing using `RangeFrom` could be implemented for `CStr`, but I'm not sure if that's useful in practice.
