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
Split Digest::Base from Digest::Algorithm #9496
Conversation
Digest::Base holds the state of a digest algorithm. Digest::Algorithm defines the API to be used as entry point. Add OpenSSL::Digest::SHA1/256/512 for convenience
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this is the right solution.
Differtiating between Digest::Algorithm
and Digest::Base
is really confusing and doesn't make much sense in terms of the API. It ends up exposing class methods on Digest::Algorithm
that can't be used on that type, only on implementing types. That's why these methods are in macro inherinted
, so that they only show up in implementing classes.
I suppose it would be a better solution to just make that macro inherited
an opt-in macro which inheriting types need to call explicitly (or maybe the inherited hook could check whether a new
method is defined and this could be automatically opt-in).
That would leave us with a single type (we could consider renaming it to Digest::Algorithm
), clearly defined class methods and an overall concise API.
I'm also skeptical of the OpenSSL types. Are they really necessary/useful? We've plans to refactor to a generic TLS API anyways, so we could try to avoid adding more APIs to OpenSSL namespace.
I tried something like that in bcardiff@c1fde24 but I didn't like that the optional module end up acting as the type to be used in a collection of algorithm. I think that when OpenSSL module is reworked, OpenSSL::Digest implementation might change and then ::Digest::Base could be merged with ::Digest::Algorithm if all the instances can be created without arguments. When that happens, we can leave ::Digest::Algorithm as base class. We can also duplicate a bit of code a don't make OpenSSL::Digest related to ::Digest but that was part of the goal in #8426 that many where happy about. |
bcardiff@c1fde24 is not really what I meant. It's unfortunate that the OpenSSL implementations' class method API is not compatible so we can't use an abstract
There's no ideal solution. But I'd pick the latter one because it's the least changes. I'm also not aware anyone showed a concrete use case for this. So it probably also has the least impact. |
I'm sorry, but all the alternatives proposed here are wrong. @bcardiff already told me what we should ideally do, and I love that. It's just that it seems we can't do that change in 0.35.1 because it doesn't align with 0.35.0. The ideal solution is:
Then the API becomes super clean: |
This proposal sounds great! |
Digest::Base
holds the state of a digest algorithm.Digest::Algorithm
defines the API to be used as entry point.Crystal native implementation like
Digest::MD5
,Digest::SHA1
are nowDigest::Algorithm
.OpenSSL::Digest
do not follow the same design asn native implementation. The user needs to input the name of the algorithm. This cause that the class methods to not work as they were defined.An attempt to extend the class methods to forward constructor arguments as:
will not work because other class methods that were defined in
Digest::Base
that has arguments.So I think the cleaner path to avoid changing the expected API is to decouple
Digest::Base
as a helper class to keep the state of the algorithm, andDigest::Algorithm
to be used as entry point.All
Digest::Algorithm
can be created without argument. So the class methods can be well defined.OpenSSL::Digest
does not fall in this case. For convenienceOpenSSL::Digest::SHA1
/SHA256
/SHA512
are defined as shameless wrapper to aOpenSSL::Digest
.Finally, it is now possible to be able to have a registry of algorithm by name as defined by
String => Digest::Algorithm.class
.Maybe if the OpenSSL module got redesigned things can be simplified since the noise is introduced by it's difference with the native implementation.
Ref: #9483
Follow-up: #8426