-
-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
consider using extension traits on Vec<u8>/&[u8] #5
Comments
I'd say And, yeah, I'd be fine with |
I would love to see this change.
When I first saw bstr, I had two thoughts:
1) This looks awesome! This is exactly what I need in so many cases?
2) This would motivate invasive changes to many crates in order to take full advantage of it.
Making `[u8]` more capable will make this much more useful and interoperable with existing crates.
|
One little hiccup that I've run into is that a lot of the current
Any thoughts on what the preferred route ought to be? |
I like the second option personally |
@lespea Could you elaborate a bit more? :) |
This commit effectively rewrites the entire API of this crate to use extension traits on `[u8]` and `Vec<u8>`. While the `BStr` and `BString` types are still present, they are now just dumb wrappers that deref to `[u8]` and `Vec<u8>`, respectively. Their primary purpose is for convenient debug impls. The motivation for this design is laid out in #5. Closes #5
This commit effectively rewrites the entire API of this crate to use extension traits on `[u8]` and `Vec<u8>`. While the `BStr` and `BString` types are still present, they are now just dumb wrappers that deref to `[u8]` and `Vec<u8>`, respectively. Their primary purpose is for convenient debug impls. The motivation for this design is laid out in #5. Closes #5
This commit effectively rewrites the entire API of this crate to use extension traits on `[u8]` and `Vec<u8>`. While the `BStr` and `BString` types are still present, they are now just dumb wrappers that deref to `[u8]` and `Vec<u8>`, respectively. Their primary purpose is for convenient debug impls. The motivation for this design is laid out in #5. Closes #5
Currently, in 0.1 of bstr, the primary way to use and manipulate byte strings is with the
BString
(owned, growable) andBStr
(borrowed slice) types. However, a major alternative design to using explicit types is to define extension traits that add more methods to theVec<u8>
and&[u8]
types.Reflecting back, I don't think I quite gave the extension trait path a thorough review before going with the explicit
BString
/BStr
types. In particular, I perceive few key advantages to using explicit types:Debug
representation that prioritizes the "stringness" ofBString
/BStr
over the "slice ofu8
" representation shown forVec<u8>
/&[u8]
. For example,"abc"
instead of[97, 98, 99]
.u8
." Serde comes to mind here.If (1) were the only benefit, I think I could be persuaded to drop that line of reasoning, although it does appeal to me aesthetically. However, in my view, (2) is a fairly significant benefit, and it's one of the most important ergonomic improvements that I look forward to whenever I bring
bstr
in to one of my crates. Otherwise, I fairly consistently define my own helper functions for printing out byte strings when I don't havebstr
, and it's honestly a pain. Especially whenVec<u8>
/&[u8]
are part of some other type.With that said, in the course of actually using
bstr
in crates, I've come to the belief that using extension traits would make using string oriented APIs much more seamless and more ergonomic overall, with the notable exception of the aforementioned problems with the debug representation. In particular, usingBString
/BStr
often requires annoying conversion routines betweenVec<u8>
/&[u8]
. e.g., Most of the raw I/O APIs in std want a&[u8]
, so you wind up needing to writemy_byte_string.as_bytes()
quite a bit, which is annoying.Moreover, using
BString
/BStr
really motivates one to use them in as many places as possible, because of aforementioned annoying conversions. But this isn't always desirable, because you might want to expose APIs in terms of&[u8]
for various reasons, including, but not limited to, not adding a public dependency onbstr
. If we were using extension traits instead, then you could just import the traits and start using the new APIs immediately.One possible alternative to this would to implement
Deref
andDerefMut
forBString
/BStr
, which would eliminate the variousas_bytes()
calls, but you still need to explicitly construct byte strings. Moreover, this kind of feels like an abuse ofDeref
.Another benefit of extension traits is that the API surface area of
bstr
could be quite a bit smaller, since many of the methods onBString
/BStr
are just re-exports of methods by the same name onVec<u8>
/&[u8]
.Overall, my sense is that this crate would be better if it used extension traits. To mitigate (but not completely solve) my
Debug
problem, we could keep theBString
/BStr
types, but remove all of their inherent methods, make them implementDeref
and add an appropriateDebug
impl. You still have to explicit convert fromVec<u8>
/&[u8]
, which is a little annoying, but I expect their use would be more limited and theDeref
impl would make them overall more convenient to use.Obviously, this is a fairly large breaking change to the current API, but given the only consumer (that I know of) is me, I think it's okay to do this. The library is called an experiment after all, and if we're going to make this change, then now would be the time to do it.
Pinging @joshtriplett and @eddyb, who I believe might have thoughts on this. (Please ping others that you think might have an opinion on this.)
The text was updated successfully, but these errors were encountered: