module Cardano.Wallet.Primitive.Types.Address.Gen
(
genAddress
, shrinkAddress
, addressParity
, Parity (..)
)
where
import Prelude
import Cardano.Wallet.Primitive.Types.Address
( Address (..) )
import Test.QuickCheck
( Gen, elements, sized )
import qualified Data.Bits as Bits
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as B8
genAddress :: Gen (Address)
genAddress :: Gen Address
genAddress = (Int -> Gen Address) -> Gen Address
forall a. (Int -> Gen a) -> Gen a
sized ((Int -> Gen Address) -> Gen Address)
-> (Int -> Gen Address) -> Gen Address
forall a b. (a -> b) -> a -> b
$ \Int
size -> [Address] -> Gen Address
forall a. [a] -> Gen a
elements ([Address] -> Gen Address) -> [Address] -> Gen Address
forall a b. (a -> b) -> a -> b
$ Int -> [Address] -> [Address]
forall a. Int -> [a] -> [a]
take (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
1 Int
size) [Address]
addresses
shrinkAddress :: Address -> [Address]
shrinkAddress :: Address -> [Address]
shrinkAddress Address
a
| Address
a Address -> Address -> Bool
forall a. Eq a => a -> a -> Bool
== Address
simplest = []
| Bool
otherwise = [Address
simplest]
where
simplest :: Address
simplest = [Address] -> Address
forall a. [a] -> a
head [Address]
addresses
addresses :: [Address]
addresses :: [Address]
addresses = Char -> Address
mkAddress (Char -> Address) -> [Char] -> [Address]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char
'0' ..]
addressParity :: Address -> Parity
addressParity :: Address -> Parity
addressParity = Int -> Parity
forall a. Integral a => a -> Parity
parity (Int -> Parity) -> (Address -> Int) -> Address -> Parity
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Address -> Int
addressPopCount
where
addressPopCount :: Address -> Int
addressPopCount :: Address -> Int
addressPopCount = (Int -> Word8 -> Int) -> Int -> ByteString -> Int
forall a. (a -> Word8 -> a) -> a -> ByteString -> a
BS.foldl' (\Int
acc -> (Int
acc Int -> Int -> Int
forall a. Num a => a -> a -> a
+) (Int -> Int) -> (Word8 -> Int) -> Word8 -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a. Bits a => a -> Int
Bits.popCount) Int
0 (ByteString -> Int) -> (Address -> ByteString) -> Address -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Address -> ByteString
unAddress
parity :: Integral a => a -> Parity
parity :: a -> Parity
parity a
a
| a -> Bool
forall a. Integral a => a -> Bool
even a
a = Parity
Even
| Bool
otherwise = Parity
Odd
data Parity = Even | Odd
deriving (Parity -> Parity -> Bool
(Parity -> Parity -> Bool)
-> (Parity -> Parity -> Bool) -> Eq Parity
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Parity -> Parity -> Bool
$c/= :: Parity -> Parity -> Bool
== :: Parity -> Parity -> Bool
$c== :: Parity -> Parity -> Bool
Eq, Int -> Parity -> ShowS
[Parity] -> ShowS
Parity -> [Char]
(Int -> Parity -> ShowS)
-> (Parity -> [Char]) -> ([Parity] -> ShowS) -> Show Parity
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [Parity] -> ShowS
$cshowList :: [Parity] -> ShowS
show :: Parity -> [Char]
$cshow :: Parity -> [Char]
showsPrec :: Int -> Parity -> ShowS
$cshowsPrec :: Int -> Parity -> ShowS
Show)
mkAddress :: Char -> Address
mkAddress :: Char -> Address
mkAddress Char
c = ByteString -> Address
Address (ByteString -> Address) -> ByteString -> Address
forall a b. (a -> b) -> a -> b
$ ByteString
"ADDR" ByteString -> Char -> ByteString
`B8.snoc` Char
c