Description
Proposal
Problem statement
Currently, the best way to evaluate the length of a CStr
is cs.to_bytes().len()
. This is not ergonomic, and may not be the best option when CStr
becomes a thin pointer.
Motivating examples or use cases
For both a fat and thin CStr
, this will provide a more intuitive method to get the length. When CStr
becomes thin, CStr::count_bytes
will be able to call strlen
directly without going through the less direct to_bytes
> to_bytes_with_nul
> slice::from_raw_parts
> len
.
Solution sketch
Add a method CStr::count_bytes
that returns its length. Currently, we can use a self.inner.len() - 1
to get the length of the string, which is a constant time operation. Once CStr
becomes thin, this will become an O(1)
call to strlen
- we just need to make it clear in documentation that this will have a performance regression at some point (as we do for the to_bytes()
methods).
The API is simple:
impl CStr {
pub fn count_bytes(&self) -> usize {
self.inner.len()
}
}
Once thin, this will become:
impl CStr {
pub fn count_bytes(&self) -> usize {
strlen(self.inner_ptr)
}
}
Alternatives
The status quo: accessing length via .to_bytes().len()
. This ACP intends to improve upon this option.
const
ness
Currenly CStr::from_ptr
uses a version of strlen
that calls libc's implementation normally, or a naive Rust implementation when const. This works via const_eval_select
which to my knowledge hasn't been okayed for internal use. So, we will not be able to make CStr::count_bytes
const stable until either that happens, or we decide our naive strlen
is always OK (making CStr::new
const is also blocked by this, or by the switch to a thin pointer).
My current implementation gates the constness under const_cstr_from_ptr
which has the same const-stable blocker.
cc @oli-obk because of your comment onconst_eval_select
here rust-lang/rust#107624 (comment) (I believe this is the RFC: rust-lang/rfcs#3352)
Naming
The name count_bytes
is up for some bikeshedding.
Links and related work
- @BurntSushi pointed out the lack of a
CStr::len
method when stabilizingCStr::is_empty
: Tracking Issue for CStr::is_empty rust#102444 (comment) - I put together a table the time complexity for different
CStr
methods based on whether or not we haveconst_eval_select
, here: Stabilizeconst_cstr_methods
rust#107624 (comment)
What happens now?
This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.