generic-str
The one true string type in Rust!
This project intends to be a proof-of-concept for an idea I had a few months back. There is lots of unsafe and requires nightly. Tested on
cargo 1.58.0-nightly (2e2a16e98 2021-11-08)
Explanation
Rust notoriously has a few different string types. The two main contenders are:
&str
which is a 'string reference'. It's non-resizable and it's mutability is limited.String
which is an 'owned string'. It's resizable and can be mutated simply.
It turns out that these two strings aren't too different. str
is just a string that's backed by a [u8]
byte slice. Similarly, String
is just a string that's backed by a Vec<u8>
.
So why are they really different types? Couldn't we theoretically have something like
type str = StringBase<[u8]>;
type String = StringBase<Vec<u8>>;
So that's what this is. It's mostly up to feature parity with the standard library strings. A lot of the standard trait implementations are there too.
I've also implemented
type str32 = StringBase<[char]>;
type String32 = StringBase<Vec<char>>;
for utf-32 applications.
generic-vec
So there was some discussion about whether Allocator
was the best abstraction for customising Vec
storage. I was very intrigured by this concept, and I made use of an implementation that RustyYato contributed in the thread in this project.
So, now I have
use generic_vec::{GenericVec, raw::Heap};
pub type String<A = Global> = OwnedString<u8, Heap<u8, A>>;
pub type OwnedString<U, S> = StringBase<GenericVec<U, S>>;
Which might look more complicated, and you'd be right. Implementation wise, GenericVec<U, Heap<U, A>>
is supposed to be identical to Vec<u8>
so it should be functionally the same as before.
But, with the added power of this storage backed system, it allows for static allocated but resizable† strings!
pub type ArrayString<const N: usize> = OwnedString<u8, UninitBuffer<[u8; N], u8>>;
And I get to re-use all of the same code from when implementing String
, because it's all implemented on the base OwnedString
type for string manipulations that needs resizablility.
†: obviously, they cannot be resized larger than the pre-defined
N
value, and it will panic in the event that you attempt to push over that.