{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.Solidity.Prim.List
(
ListN
) where
import Basement.Nat (NatWithinBound)
import Basement.Sized.List (ListN, toListN_, unListN)
import qualified Basement.Sized.List as SL (mapM_, replicateM)
import Control.Monad (replicateM)
import GHC.Exts (IsList (..))
import GHC.TypeLits (KnownNat)
import Data.Solidity.Abi (AbiGet (..), AbiPut (..), AbiType (..))
import Data.Solidity.Prim.Int (getWord256, putWord256)
instance AbiType [a] where
isDynamic :: Proxy [a] -> Bool
isDynamic Proxy [a]
_ = Bool
True
instance AbiPut a => AbiPut [a] where
abiPut :: Putter [a]
abiPut [a]
l = do Putter Word256
putWord256 Putter Word256 -> Putter Word256
forall a b. (a -> b) -> a -> b
$ Int -> Word256
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
l)
(a -> Put) -> Putter [a]
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> Put
forall a. AbiPut a => Putter a
abiPut [a]
l
instance AbiGet a => AbiGet [a] where
abiGet :: Get [a]
abiGet = do Int
len <- Word256 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word256 -> Int) -> Get Word256 -> Get Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word256
getWord256
Int -> Get a -> Get [a]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
len Get a
forall a. AbiGet a => Get a
abiGet
instance AbiType (ListN n a) where
isDynamic :: Proxy (ListN n a) -> Bool
isDynamic Proxy (ListN n a)
_ = Bool
False
instance AbiPut a => AbiPut (ListN n a) where
abiPut :: Putter (ListN n a)
abiPut = (a -> Put) -> Putter (ListN n a)
forall (m :: * -> *) a b (n :: Nat).
Monad m =>
(a -> m b) -> ListN n a -> m ()
SL.mapM_ a -> Put
forall a. AbiPut a => Putter a
abiPut
instance (NatWithinBound Int n, KnownNat n, AbiGet a) => AbiGet (ListN n a) where
abiGet :: Get (ListN n a)
abiGet = Get a -> Get (ListN n a)
forall (n :: Nat) (m :: * -> *) a.
(NatWithinBound Int n, Monad m, KnownNat n) =>
m a -> m (ListN n a)
SL.replicateM Get a
forall a. AbiGet a => Get a
abiGet
instance (NatWithinBound Int n, KnownNat n) => IsList (ListN n a) where
type Item (ListN n a) = a
fromList :: [Item (ListN n a)] -> ListN n a
fromList = [Item (ListN n a)] -> ListN n a
forall (n :: Nat) a.
(HasCallStack, NatWithinBound Int n, KnownNat n) =>
[a] -> ListN n a
toListN_
toList :: ListN n a -> [Item (ListN n a)]
toList = ListN n a -> [Item (ListN n a)]
forall (n :: Nat) a. ListN n a -> [a]
unListN