-
Notifications
You must be signed in to change notification settings - Fork 70
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
Cannot read own enum values #27
Comments
@amalloy does the naming strategy stuff you added help with this? On May 30, 2012, at 2:07 AM, jheander wrote:
|
Yes, you can pass a naming strategy to the protodef call now which will let you convert from protobuf to keywords and back in whatever manner you like. |
Great. @amalloy, can you post a quick example here? |
It should work to simply modify the (def Quiz (protodef com.example.Example$Quiz
(reify PersistentProtocolBufferMap$Def$NamingStrategy
(protoName [this clojure-name]
(name clojure-name))
(clojureName [this proto-name]
(keyword proto-name))))) But I'm not totally sure I understand the problem behind this issue. @jheander, does this resolve your problem? |
Well, I guess it would resolve the problem. However I really like the default naming strategy and the convenience of using idiomatic names within clojure. My problem is basically just that the naming transformations are not reversible. Currently I accept streamed protobuf as input, do some transformations in clojure and output protobuf again but the last step fails if I don't add an extra step where I explicitly convert all the enums back to uppercase (and remember which enums that are likely to be in the output). This feels a bit weird since its the same tool that is used for the whole chain :) Maybe implement some kind of name lookup table that will map the lowercase keyword to the correct enum or disable case transformations for enums in the default policy like in previous versions of clojure-protobuf did? |
I agree with @jheander about the desirability of having it work both ways. I was surprised to find that (protobuf Request :type :foo :action :get) did not work even though that is what the repl shows me when I do a protobuf-load for that data. |
I added code to address this issue in goodwink@43c7cb2 if anyone else cares to use them or if you'd like me to open a pull request for it. |
I think your updated convertUnderscores strategy is better than before since it now only does what the name advertises. It is also reversible much more often and generally seems in-line with how googles implementations for other languages choose to transform the names. And as a bonus it solves our common problem :) The new naming strategy convertUnderscoresAndCase could probably break both enums and keys since it is not really reversible if the original name has mixed case (CamelCase or other weird convention :)) or if it is already lower-case. Since small-caps are recommended by google for keys it would probably break most keys, but work perfecly with enums. // Johan |
@jheander agreed on the new naming strategy...the main problem is not having separate methods to handle enums and keys when their naming rules are different on the protobuf side. I worked around this by ignoring the google recommendation that keys be lower case and made them upper case just like enums, but this is at best temporary since it's ugly and impacts usability negatively in non-clojure clients. Probably the solution is either to expand the naming strategy functionality to allow separate naming strategies for keys and enums or else to just put up with upper-case on the clojure side for enums and only convert underscores to dashes. |
Yes, actually for enums I kind of prefer the latter alternative to only convert underscores to dashes since this would make the keys idiomatic (if following the google recommendations of lowercase, underscore separated keys) and would keep the enums usable and also make it easy to convert the enums to integers, without first running it backwards through the naming strategy, if needed for DB storage: (defn answer->int [kw]
(.getNumber (Enum/valueOf Example$Answer (name kw)))) |
I think the enums would still need to have dashes converted back to underscores in order to use them like that, right? |
Yeah, you're right, didn't think of that first :) Guess you would have to use the naming strategy then anyways... |
me too. I have the trouble that when I print a protobuf message and then to convert back into a protobuf structure it doesn't work for enums. That is the most important thing to fix. Secondarily I like the ideomatic names, so WORK_TYPE becomes :work-type. I understand such a conversion isn't well defined since it could be lossy if protobuf enums are case sensitive. If that is so, perhaps just do the conversion in print for "standard" enums, that is enums that are all the same case. |
It seems that the code currently requires enums to be keywords in the original case when loading them from a map, but converts them to lower case as soon as they are loaded. This gives an error if you persist it to a database and then load it and try to convert it to protobuf again.
Minimum example:
example.proto
Failing test:
The text was updated successfully, but these errors were encountered: