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
[LTB-61] Add ToJSON instance for ConfigRec #53
base: master
Are you sure you want to change the base?
Conversation
Problem: There is no way to display partial or final config. Solution: Implmement `ToJSON` instance for `ConfigRec`
@kirelagin There are no tests for now, as I am still thinking about better way to do this. Firstly I don't like that So one way I thought about solving this problem is creating a @kirelagin do you have a better proposal? |
Also @kirelagin I was thinking that it would be cool if we keep some information about sources of different options in final config and present it if necessary, so users wouldn't need to manually debug and track exact place where an option came from |
ItemSumP inner -> A.object $ configToJsonList inner | ||
ItemSumF inner -> A.object $ configToJsonList inner |
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.
This might be implemented semantically wrong, because I haven't understood meaning of this
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 have no idea either 😅. I believe, @pasqu4le added sum types.
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.
Yep, I added support for sum types, although quite some time ago, so I had to check the code again because I forgot how 😅
Anyway, this seems to be semantically correct.
If the confusion is about why there are 2 ItemSum
I am not entirely sure, I recall something about them requiring different constraints but I cannot find this now and judging by some comments in the PR this difference might have been solved at some point.
In other terms, unless I am missing something, it looks like we could have had a single:
ItemSum :: Item' k (l ::+ is) -> Item k (l ::+ is)
just like we have a single ItemSub
and the implementation here is indeed correct.
P.s. I could check this for sure and open up another PR to fix this if necessary
Hmmm, I guess I don’t understand something. If the config is “final”, then there can be do undefined options in it. If the config is “partial”, then you just don’t add undefined options to the resulting JSON object. Isn’t that right? |
That's not entirely true for sum types, because basically they are implemented with product types you end up with "undefined" branches, which is to say equivalent of non-used constructors of a sum-type. For example this: type ExampleParams =
'[ "params" ::+
'[ "basic" ::- OtherType
, "advanced" ::- OtherType
]
] could be parsed (and finalized) from this: params:
paramsType: "basic"
basic:
[... othertype ...] and "advanced" would be "undefined". |
I am not sure I understand the need for the Final configurations are complete, so the steps of: The same can be said about partial configurations (except of course that |
@pasqu4le the whole purpose of this is to show configs to human and let them debug why config value is not which they expected. I added
|
Ok, so it seems to me we'd like to obtain two things:
Ideally we'd have a
I suggest to go with this approach, it could be done fairly simply by adding a boolean argument to We define the Of course we can then have the instance OptionsToJsonList k is => ToJSON (ConfigRec k is) pass said argument already to obtain a valid, without As for the debugging-helpful representation, you can make a newtype for it and have its instance use |
Regarding your ideas about sources I guess to be able to report where a configuration came from we'd need to store this information in TBH I don't know what's the current status of lootbox on the matter. |
Problem: String have strange behaviour in JSON roundtrip property tests. Solution: Replace String with Text.
@pasqu4le @kirelagin take a look please when you have time. |
import Loot.Config.Record ((:::), (::<), (::+), (::-), ConfigKind, | ||
ConfigRec, Item (ItemOptionP, ItemOptionF, ItemSub, ItemSumP, ItemSumF, ItemBranchP, ItemBranchF), | ||
ItemKind, SumSelection) |
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.
This import list is odd, it goes outside the 80 line length limit and you use all the Item
constructors anyway, so I suggest:
import Loot.Config.Record ((:::), (::<), (::+), (::-), ConfigKind, | |
ConfigRec, Item (ItemOptionP, ItemOptionF, ItemSub, ItemSumP, ItemSumF, ItemBranchP, ItemBranchF), | |
ItemKind, SumSelection) | |
import Loot.Config.Record ((:::), (::<), (::+), (::-), ConfigKind, ConfigRec, | |
Item (..), ItemKind, SumSelection) |
( fromString $ symbolVal (Proxy :: Proxy l) | ||
, A.object $ configToJsonList inner | ||
) : configToJsonList rest | ||
let label = fromString $ symbolVal (Proxy :: Proxy l) |
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.
fromString $ symbolVal (Proxy :: Proxy l)
is used in several places, I suggest extracting it into a function.
Overall LGTM, I think |
Problem: We have FromJSON instance so we can parse configuration from valid json or yaml. But there are cases when we want print this config file, send, log, etc. So it's useful to have ToJSON instance too. Solution: Add ToJSON instance for ConfigRec, converting to json happens with help of OptionsToJson class which recursively goes through config file and convert values. Note: we independently implemented `ToJSON` in this PR before we noticed #53
Problem: We have FromJSON instance so we can parse configuration from valid json or yaml. But there are cases when we want print this config file, send, log, etc. So it's useful to have ToJSON instance too. Solution: Add ToJSON instance for ConfigRec, converting to json happens with help of OptionsToJson class which recursively goes through config file and convert values. Note: we independently implemented `ToJSON` in this PR before we noticed #53
Problem: This was made here #53. But this PR became still. It'll be good to proceed this PR and add Buildable instances, cause it's quite useful. We not going to merge #53, because Json instances was added recently independent from this PR (we didn't know about it). Solution: Move Buildable instances (along with tests) form #53.
Problem: This was made here #53. But this PR became still. It'll be good to proceed this PR and add Buildable instances, cause it's quite useful. We not going to merge #53, because Json instances was added recently independent from this PR (we didn't know about it). Solution: Move Buildable instances (along with tests) form #53.
Problem: This was made here #53. But this PR became still. It'll be good to proceed this PR and add Buildable instances, cause it's quite useful. We not going to merge #53, because Json instances was added recently independent from this PR (we didn't know about it). Solution: Move Buildable instances (along with tests) form #53.
Problem: There is no way to display partial or final config.
Solution: Implement
ToJSON
instance forConfigRec