Skip to content

Commit

Permalink
[#272] DerivingVia for Generic table codecs
Browse files Browse the repository at this point in the history
Resolves #272
  • Loading branch information
vrom911 committed May 19, 2020
1 parent c1b8881 commit 6436c58
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 7 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ The changelog is available [on GitHub][2].
Export a function for parsing TOML keys.
* [#311](https://github.com/kowainik/tomland/issues/311):
Reimplement custom `TomlState` instead of using `MaybeT` and `State`.
* [#272](https://github.com/kowainik/tomland/issues/272):
Add `TomlTable` newtype to be used in generic `DerivingVia`.

## 1.2.1.0 — Nov 6, 2019

Expand Down
28 changes: 28 additions & 0 deletions examples/Main.hs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
{-# OPTIONS -Wno-unused-top-binds #-}

{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DerivingVia #-}

module Main (main) where

import Control.Applicative ((<|>))
import Control.Arrow ((>>>))
import Data.Hashable (Hashable)
import Data.HashSet (HashSet)
import Data.ByteString (ByteString)
import Data.IntSet (IntSet)
import Data.List.NonEmpty (NonEmpty)
import Data.Map.Strict (Map)
Expand All @@ -18,6 +21,7 @@ import GHC.Generics (Generic)
import Toml (TomlCodec, TomlParseError (..), pretty, (.=), (<!>))
import Toml.Type (TOML (..), Value (..))
import Toml.Type.Edsl (mkToml, table, (=:))
import Toml.Codec.Generic (TomlTable (..), stripTypeNameCodec, HasCodec (..), ByteStringAsBytes (..))

import qualified Data.Text.IO as TIO

Expand Down Expand Up @@ -177,6 +181,24 @@ testT = Test
<!> Toml.match (Toml._Right >>> Toml._Double)
) "either"

data GenericPerson = GenericPerson
{ genericPersonName :: !Text
, genericPersonAddress :: !Address
} deriving stock (Generic)

data Address = Address
{ addressStreet :: !Text
, addressHouse :: !Int
} deriving stock (Generic)
deriving HasCodec via (TomlTable Address)

testGeneric :: TomlCodec GenericPerson
testGeneric = stripTypeNameCodec

newtype MyByteString = MyByteString
{ unMyByteString :: ByteString
} deriving HasCodec via ByteStringAsBytes

main :: IO ()
main = do
TIO.putStrLn "=== Printing manually specified TOML ==="
Expand All @@ -194,6 +216,12 @@ main = do
Left msgs -> Toml.prettyTomlDecodeErrors msgs
Right test -> Toml.encode testT test

TIO.putStrLn "=== Testing Deriving Via ==="
genericFile <- TIO.readFile "examples/generic.toml"
TIO.putStrLn $ case Toml.decode testGeneric genericFile of
Left msg -> Toml.prettyTomlDecodeErrors msg
Right test -> Toml.encode testGeneric test

myToml :: TOML
myToml = mkToml $ do
"a" =: Bool True
Expand Down
5 changes: 5 additions & 0 deletions examples/generic.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name = "foo"

[address]
addressStreet = "Bar"
addressHouse = 42
10 changes: 3 additions & 7 deletions src/Toml/Codec/Generic.hs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ module Toml.Codec.Generic
, ByteStringAsBytes (..)
, LByteStringAsText (..)
, LByteStringAsBytes (..)

-- * Deriving Via
, TomlTable (..)
) where

import Data.ByteString (ByteString)
Expand Down Expand Up @@ -669,10 +672,6 @@ instance HasCodec a => HasCodec (Last a) where
hasCodec = Toml.last (hasCodec @a)
{-# INLINE hasCodec #-}

{-
TODO: uncomment when higher-kinded roles will be implemented
* https://github.com/ghc-proposals/ghc-proposals/pull/233
{- | @newtype@ for generic deriving of 'HasCodec' typeclass for custom data
types that should we wrapped into separate table. Use it only for data types
that are fields of another data types.
Expand Down Expand Up @@ -712,7 +711,6 @@ instance (Generic a, GenericCodec (Rep a)) => HasCodec (TomlTable a) where

instance (Generic a, GenericCodec (Rep a)) => HasItemCodec (TomlTable a) where
hasItemCodec = Right $ Toml.diwrap $ genericCodec @a
-}

{- $bytestring
There are two ways to encode 'ByteString' in TOML:
Expand All @@ -726,9 +724,7 @@ To handle all these cases, @tomland@ provides helpful newtypes, specifically:
* 'ByteStringAsBytes'
* 'LByteStringAsText'
* 'LByteStringAsBytes'
-}
{- TODO: uncomment when the same GHC issue as above is resolved:
As a bonus, on GHC >= 8.6 you can use these newtypes with the @DerivingVia@
extensions for your own 'ByteString' types.
Expand Down
4 changes: 4 additions & 0 deletions tomland.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,12 @@ executable readme

executable play-tomland
import: common-options
-- We are using DerivingVia that works only with > 8.6
if impl(ghc < 8.6)
buildable: False
main-is: Main.hs
build-depends: tomland
, bytestring
, containers
, hashable
, text
Expand Down

0 comments on commit 6436c58

Please sign in to comment.