Skip to content

Commit

Permalink
Add ToJSON instances for IntN, UintN and generated datatypes (#136)
Browse files Browse the repository at this point in the history
* Add ToJSON instances for IntN and UIntN

* Add ToJSON instances to generated data types
  • Loading branch information
RubenAstudillo authored Sep 30, 2022
1 parent c242f23 commit 60db7fc
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/ethereum/package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ dependencies:
- text >1.2 && <1.3
- vinyl >0.5 && <0.14
- aeson >1.2 && <2.2
- aeson-casing >=0.2 && <0.3
- tagged >0.8 && <0.9
- memory >0.14 && <0.17
- relapse >=1.0 && <2.0
Expand Down
11 changes: 10 additions & 1 deletion packages/ethereum/src/Network/Ethereum/Contract/TH.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
Expand Down Expand Up @@ -45,7 +46,8 @@ module Network.Ethereum.Contract.TH

import Control.Applicative ((<|>))
import Control.Monad (replicateM, (<=<))
import qualified Data.Aeson as Aeson (encode)
import qualified Data.Aeson as Aeson
import Data.Aeson.Casing (aesonDrop, camelCase)
import Data.ByteArray (convert)
import Data.ByteArray.HexString (HexString)
import Data.Char (toLower, toUpper)
Expand Down Expand Up @@ -207,6 +209,7 @@ mkDecl ev@(DEvent uncheckedName inputs anonymous) = sequence
, instanceD' nonIndexedName (conT ''AbiGet) []
, dataD' allName (recC allName (map (\(n, a) -> (\(b,t) -> return (n,b,t)) <=< toBang <=< typeEventQ $ a) allArgs)) derivingD
, instanceD' allName (conT ''Generic) []
, instanceD' allName (conT ''Aeson.ToJSON) [funD' 'Aeson.toJSON [] [| Aeson.genericToJSON $ aesonDrop nameL (init' . camelCase) |] ]
, instanceD (cxt [])
(pure $ ConT ''IndexedEvent `AppT` ConT indexedName `AppT` ConT nonIndexedName `AppT` ConT allName)
[funD' 'isAnonymous [] [|const anonymous|]]
Expand All @@ -216,6 +219,7 @@ mkDecl ev@(DEvent uncheckedName inputs anonymous) = sequence
]
where
name = if toLower (T.head uncheckedName) == Char.toUpper (T.head uncheckedName) then "EvT" <> uncheckedName else uncheckedName
!nameL = length (T.unpack name)
topics = [Just (T.unpack $ eventId ev)] <> replicate (length indexedArgs) Nothing
toBang ty = bangType (bang sourceNoUnpack sourceStrict) (return ty)
tag (n, ty) = AppT (AppT (ConT ''Tagged) (LitT $ NumTyLit n)) <$> typeEventQ ty
Expand Down Expand Up @@ -251,6 +255,11 @@ mkDecl fun@(DFunction name constant inputs outputs) = (++)

mkDecl _ = return []

-- | Best-effort name recovery from ADT to original 'eveArgName' on inputs.
init' :: String -> String
init' [] = []
init' xs = if Char.isDigit (last xs) then xs else init xs

mkContractDecl :: Text -> Text -> Text -> Declaration -> DecsQ
mkContractDecl name a b (DConstructor inputs) = sequence
[ dataD' dataName (normalC dataName bangInput) derivingD
Expand Down
4 changes: 3 additions & 1 deletion packages/ethereum/web3-ethereum.cabal
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cabal-version: 1.12

-- This file has been generated from package.yaml by hpack version 0.34.4.
-- This file has been generated from package.yaml by hpack version 0.34.7.
--
-- see: https://github.com/sol/hpack

Expand Down Expand Up @@ -58,6 +58,7 @@ library
build-depends:
OneTuple >0.2 && <0.4
, aeson >1.2 && <2.2
, aeson-casing ==0.2.*
, base >4.11 && <4.16
, bytestring >0.10 && <0.11
, data-default >0.7 && <0.8
Expand Down Expand Up @@ -122,6 +123,7 @@ test-suite tests
build-depends:
OneTuple >0.2 && <0.4
, aeson >1.2 && <2.2
, aeson-casing ==0.2.*
, base >4.11 && <4.16
, bytestring >0.10 && <0.11
, data-default >0.7 && <0.8
Expand Down
7 changes: 7 additions & 0 deletions packages/solidity/src/Data/Solidity/Prim/Int.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ module Data.Solidity.Prim.Int
import qualified Basement.Numerical.Number as Basement (toInteger)
import Basement.Types.Word256 (Word256 (Word256))
import qualified Basement.Types.Word256 as Basement (quot, rem)
import Data.Aeson (ToJSON(..))
import Data.Bits (Bits (testBit), (.&.))
import Data.Proxy (Proxy (..))
import Data.Serialize (Get, Putter, Serialize (get, put))
Expand Down Expand Up @@ -90,6 +91,9 @@ instance (n <= 256) => AbiGet (UIntN n) where
instance (n <= 256) => AbiPut (UIntN n) where
abiPut = putWord256 . unUIntN

instance (KnownNat n, n <= 256) => ToJSON (UIntN n) where
toJSON = toJSON . toInteger

-- | Signed integer with fixed length in bits.
newtype IntN (n :: Nat) = IntN { unIntN :: Word256 }
deriving (Eq, Ord, Enum, Bits, Generic)
Expand Down Expand Up @@ -130,6 +134,9 @@ instance (n <= 256) => AbiGet (IntN n) where
instance (n <= 256) => AbiPut (IntN n) where
abiPut = putWord256 . unIntN

instance (KnownNat n, n <= 256) => ToJSON (IntN n) where
toJSON = toJSON . toInteger

-- | Serialize 256 bit unsigned integer.
putWord256 :: Putter Word256
putWord256 (Word256 a3 a2 a1 a0) =
Expand Down

0 comments on commit 60db7fc

Please sign in to comment.