-
Notifications
You must be signed in to change notification settings - Fork 115
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
Adding a Base64 type #42
Comments
It's an interesting idea, though I think I'd have to see some examples of it in use to get a better idea of how the API should be structured. (For that matter, I'm not sure it even needs to be part of this crate.) If you had the opportunity to create a Also, it's not just as simple as |
You can infer based on the Base64 you get if its padded or wrapped - its apparent in the structure. You cannot tell, however, if it was meant to be UrlSafe or not, if the string never uses the Default or UrlSafe substitution characters. That being said, it is all fairly subjective on whether that is even valuable knowledge or not! It would be really strange to put someone into a situation as the owner of a Base64 object to try appending two Base64s with no conflict even if they used the two different encoding schemes (albeit in the same vein appending Base64's where one is padded / wrapped and one is not would also require handling).
That is the whole argument. Right now it is perfectly normal when using base64 to pass around the encoded data as any of the various forms of u8 containers. But sending around any of those containers is information lossy because the data structure doesn't enforce its interpretation as base64.
Absolutely agreed. I think this weekend I'll try impl'ing this as a separate crate. If it becomes a popular UX pattern it could be merged any time after that. |
One small point -- you can't necessarily infer padding or wrapping because you might only ever see input that has
I was referring to passing around the data that you would get if you decoded the base64, not the ascii bytes that could be interpreted as base64. Anyway, I'm curious to see what you come up with. |
Almost forgot to do this! Just threw together an example over here. [1] You are right, in that there is no real intuitive way to persist the config data in the struct without allocations (Configs would have to be zero sized phantomdata), and you need it around all the way for decoding purposes and for validation. That being said, I think I discovered why having a The only piece that is missing is deserialization for this type that validates its actually base64 when being passed generic data. I'll try to do that soon™. That would be where you want the conditionality. For libraries in Rust, passing around base64 as a concrete type with decode guarantees is a real ergonomic win in my book. [1] There are some hacks here around the public base64 api, like unwrapping the decode. |
As a Haskell hacker too, I agree. Strong types communicate intent as well as contracts. |
Would be also nice while using serde. Something like this comes to mind:
|
Interesting. I do like the idea in general of having less magic in a custom serializer and more explicit DTOs. Perhaps there's room for that in the |
I realize this is an ancient issue, but I thought I would mention that I implemented an alternative base64 crate that may be a little better fit for a strongly typed concept like this. It's called |
Rust is at its best when you are using strong typing to indicate meaning. While in essence a base64 encoded string is always a
[u8]
, functions that want a base64 encoded string would often rather be more specific than just takingString
,&str
,[u8]
,Vec<u8>
, etc. Hence, aBase64<C>
type - representing an encoded string, it could have convenience methods for converting into / from all the various string representations and collections, and would let library authors be more explicit in wanting a base64.It also seems to be to be much more newbie friendly to show them an api like:
Instead of just asking for a string and saying it should be base64:
There certainly is an argument publically facing APIs shouldn't be asking for data in base64, it should be doing that conversion internally. But even internal to consumer libraries, having concrete types is still very useful for readability and maintainability - you encode something somewhere, and then have to keep annotating your uses of it in other functions and structs as being base64.
This is similar to how
Url
andUri
types work in other crates. They internally use Strings or Vecs but expose a type to avoid ambiguity when handling it, and then have a range of convenience into's and from's to get coerce them into the standard types.The
<C>
generic is so that you can require theDefault
orUrlSafe
encoding scheme - otherwise you have to manually inspect an unsanitized input string from anywhere you cannot perfectly trust to check for the illegal characters. Another option would have to haveBase64
be an enum ofDefault
andUrlSafe
, but that becomes a runtime variant match check with cumbersome need to match on it.A related issue is #17, where having an actual Base64 type would obviously implement the specialized display.
I wouldn't mind forking and trying to draft out a Base64 type if you are at all interested!
The text was updated successfully, but these errors were encountered: