flexstr
flexstr copied to clipboard
Custom Ref/Cow to preserve `&'static str`?
This was also one of they key early features for KString
so that liquid
could pass around data throughout the program and avoid allocations for this data.
I'm not sure I understand. LocalStr
and SharedStr
are literally copying the &'static str
ref on clone so it should be approx. the same speed as copying the ref itself (one extra machine word - 24 bytes vs 16 byte fat pointer)
Maybe you are talking about onboarding? If you use from_static
or local_str!/shared_str!
these are compile time wrapper over the literal. Zero cost. They interop with other Local/Shared strings.
KStringCow and KStringRef are roughly
enum KStringCow<'s> {
Owned(Box<str>),
Literal(&'static str),
Borrowed(&'s str),
}
enum KStringRef<'s> {
Literal(&'static str),
Borrowed(&'s str),
}
This let's me have functions that return references that I can turn back into owned types without losing track of the 'static
lifetime.
Might need to see an example sometime. For some reason I'm just not getting it. If you borrow, you'd need to have a copy of the owned item or else the borrow wouldn't borrow. If you have a static...well, you have a static.
Are you talking something like my conditional ownership feature? (a side effect of using Rc
/Arc
) Essentially I advocate passing by &SharedStr
as you can always clone()
but the clone is just a ref count bump never an allocation/copy (another reason why I like Rc
/Arc
over Box
I should add).
In liquid, some data is dynamically generated and some comes from a previous allocation. I could still use a Cow<'s, SharedStr>
. I'll have to think about the trade offs of that vs a custom Cow.
Ok, if you can point me to a worked example or spot in the source that illustrates this. I'm not sure I 100% follow the use case (because in my mind, FlexStr is the antithesis of Cow
in RO scenarios so tryign to understand why you'd want ot bring cow back into it, For example: why not pass &SharedStr
instead? If you need an owned copy, clone, else use as is)
In "liquid", you can directly access the elements of an Array or the members of an Object. There are also some implicit fields, .first
, .last
, and .size
. Rather than store an extra element in the Object and Array for .size
, .size
is dynamically generated; there is no data to make a reference to.
See https://github.com/cobalt-org/liquid-rust/blob/master/crates/core/src/model/find.rs#L161
but like I said, a Cow<'s, SharedStr>
might work
For more context on liquid, see https://shopify.github.io/liquid/
I was thinking the other way around (passing in, not returning). I can definitely see use cases where you want to return a 'view' into something but don't necessarily want to copy it... or maybe you have conditional ownership (like what you are doing it seems).
Early on I played with ideas like having a 3rd and 4th type for this (I called it BStringy
before someone took my stringy
name and I went with FlexStr
). I also played with the idea of integrating borrowing into my main type as a 4th variant but I didn't want the user to have to have deal with type annotations for non-borrowed use (I know they scare a lot of new Rust users).
I'll do more thinking on what makes sense, but not against bringing that idea back.
(I know they scare a lot of new Rust users).
I would assume a new Rust user would generally not be using one of these crates :)
However, a couple items down on my priority list is creating yet-another string type, one focused on ease of use and general performance. The idea is to have as few lifetimes in this API as possible, so each string function would return an owned type. See https://docs.rs/eztd/latest/eztd/struct.String.html and https://epage.github.io/blog/2021/09/learning-rust/
You kinda just described my goal with FlexStr
:-) Just not done yet. Well, not exactly I guess. I'm going more for easy String
replacement with better performance in immutable usage scenarios, not focusing on ease of use particularly.
I figured out how to support borrowed strings. In hindsight it was obvious. Will be in next release.