Closed everythingfunctional closed 4 years ago
Hi @everythingfunctional, thanks for using tomland
and opening an issue! Unfortunately, tomland
doesn't have out-of-the-box solution for this case. However, I can see how this can be useful in some cases. So I don't mind having such function implemented in tomland
:slightly_smiling_face:
A few notes about the implementation:
Key
type is represented as a list of Text
pieces, so the returning type will be something like Map Key a
or Map Text a
. Libraries like aeson
provide a custom abstraction like FromJSONKey
so you can have your custom Map
keys. But tomland
uses combinator-based approach instead of typeclasses-based.
https://github.com/kowainik/tomland/blob/6ca6ed3a3d6e1bbcd2b7b06ac82238ef56b00ccc/src/Toml/PrefixTree.hs#L78-L81So I think that we can have a function like:
tableMapCodec
:: Ord key
=> BiMap Key key -- ^ Bidirectional converter between TOML and Map keys
-> Key -- ^ Table name key
-> TomlCodec val -- ^ Codec for map values
-> TomlCodec (Map key val)
I'm still a bit new to doing stuff this advanced in Haskell. I'd be happy to take a shot at implementing such a function, but I'll need some guidance on where to start, where to put it, and what might be involved.
@everythingfunctional No worries :slightly_smiling_face: I can give a few pointers to the implementation.
BiMap e a b
is just a pair of functions to convert between a
and b
, where conversion can fail with an error of type e
. I believe a good starting point would be to implement a few standard bidirectional converters, like TomlBiMap Key Text and
TomlBiMap Key String. So
TomlBiMap Key Textis a pair of functions to get some arbitrary
Textfrom TOML
Keyand vice versa. I guess it's always possible to key
Textfrom
Key` but not vice versa.
https://github.com/kowainik/tomland/blob/6ca6ed3a3d6e1bbcd2b7b06ac82238ef56b00ccc/src/Toml/Bi/Map.hs#L127-L131
https://github.com/kowainik/tomland/blob/6ca6ed3a3d6e1bbcd2b7b06ac82238ef56b00ccc/src/Toml/Bi/Map.hs#L201-L202TomlBiMap
error type by adding a constructor like InvalidKey Key
. But in the beginning, implementation can simply use the ArbitraryError
constructor.
https://github.com/kowainik/tomland/blob/6ca6ed3a3d6e1bbcd2b7b06ac82238ef56b00ccc/src/Toml/Bi/Map.hs#L205-L216After that, you can try to implement tableMapCodec
. You may found two existing functions useful to look at to get an idea of how to implement it: tableCodec
and mapCodec
. The general idea is the following:
TOML
).tomlPairs
field of the type HashMap Key AnyValue
.Map Key val
back.https://github.com/kowainik/tomland/blob/6ca6ed3a3d6e1bbcd2b7b06ac82238ef56b00ccc/src/Toml/Bi/Combinators.hs#L381-L397 https://github.com/kowainik/tomland/blob/6ca6ed3a3d6e1bbcd2b7b06ac82238ef56b00ccc/src/Toml/Bi/Combinators.hs#L481-L515
Feel free to ask any further questions :slightly_smiling_face:
Resolved by #255. Thanks again, @everythingfunctional!
I'm trying to write something to parse into a Map, where the keys in the toml file are the keys in the map. I can't seem to find any way of doing this.
Basically I need something like the following.
These keys are going to be in a table, so if that makes things more concrete, what I really want would be more like
An example of the toml file would be something like
So I know I'll need a Codec to match the values, since those aren't a simple type, and I know the table the keys will be directly under, but I need to parse each of the keys into my data structure.
Sorry if this was a bit disorganized. Hopefully that's enough info to see what I'm after.