{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances,UndecidableInstances ,NoMonomorphismRestriction #-}
module Flat.Instances.Mono
  ( sizeSequence
  , encodeSequence
  , decodeSequence
  , sizeList
  , encodeList
  , decodeList
  , sizeSet
  , encodeSet
  , decodeSet
  , sizeMap
  , encodeMap
  , decodeMap
  , AsArray(..)
  , AsList(..)
  , AsSet(..)
  , AsMap(..)
  )
where

import           Data.MonoTraversable           ( Element
                                                , ofoldl'
                                                , otoList
                                                --, olength
                                                , MonoFoldable
                                                )
import           Data.Sequences                 ( IsSequence )
import qualified Data.Sequences                as S
import           Data.Containers
import           Flat.Instances.Util
import qualified Data.Foldable                 as F

-- $setup
-- >>> import Flat.Instances.Base()
-- >>> import Flat.Instances.Test
-- >>> import Data.Word    
-- >>> import qualified Data.Set
-- >>> import qualified Data.Map

{-|
Sequences are defined as Arrays:

Array v = A0
        | A1 v (Array v)
        | A2 v v (Array v)
        ...
        | A255 ... (Array v)

In practice, this means that the sequence is encoded as a sequence of blocks of up to 255 elements, with every block preceded by the count of the elements in the block and a final 0-length block.

Lists are defined as:

List a ≡  Nil
        | Cons a (List a)

The AsList/AsArray wrappers can be used to serialise sequences as Lists or Arrays

>>> tst $ AsArray ([]::[()])
(True,8,[0])

>>> tst $ AsArray [11::Word8,22,33]
(True,40,[3,11,22,33,0])

>>> tst $ AsList ([]::[()])
(True,1,[0])

>>> tst (AsList [11::Word8,22,33])
(True,28,[133,197,164,32])

>>> tst (AsSet (Data.Set.fromList [11::Word8,22,33]))
(True,28,[133,197,164,32])

-}
newtype AsArray a =
  AsArray
    { AsArray a -> a
unArray :: a
    } deriving (Int -> AsArray a -> ShowS
[AsArray a] -> ShowS
AsArray a -> String
(Int -> AsArray a -> ShowS)
-> (AsArray a -> String)
-> ([AsArray a] -> ShowS)
-> Show (AsArray a)
forall a. Show a => Int -> AsArray a -> ShowS
forall a. Show a => [AsArray a] -> ShowS
forall a. Show a => AsArray a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AsArray a] -> ShowS
$cshowList :: forall a. Show a => [AsArray a] -> ShowS
show :: AsArray a -> String
$cshow :: forall a. Show a => AsArray a -> String
showsPrec :: Int -> AsArray a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> AsArray a -> ShowS
Show,AsArray a -> AsArray a -> Bool
(AsArray a -> AsArray a -> Bool)
-> (AsArray a -> AsArray a -> Bool) -> Eq (AsArray a)
forall a. Eq a => AsArray a -> AsArray a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AsArray a -> AsArray a -> Bool
$c/= :: forall a. Eq a => AsArray a -> AsArray a -> Bool
== :: AsArray a -> AsArray a -> Bool
$c== :: forall a. Eq a => AsArray a -> AsArray a -> Bool
Eq,Eq (AsArray a)
Eq (AsArray a)
-> (AsArray a -> AsArray a -> Ordering)
-> (AsArray a -> AsArray a -> Bool)
-> (AsArray a -> AsArray a -> Bool)
-> (AsArray a -> AsArray a -> Bool)
-> (AsArray a -> AsArray a -> Bool)
-> (AsArray a -> AsArray a -> AsArray a)
-> (AsArray a -> AsArray a -> AsArray a)
-> Ord (AsArray a)
AsArray a -> AsArray a -> Bool
AsArray a -> AsArray a -> Ordering
AsArray a -> AsArray a -> AsArray a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (AsArray a)
forall a. Ord a => AsArray a -> AsArray a -> Bool
forall a. Ord a => AsArray a -> AsArray a -> Ordering
forall a. Ord a => AsArray a -> AsArray a -> AsArray a
min :: AsArray a -> AsArray a -> AsArray a
$cmin :: forall a. Ord a => AsArray a -> AsArray a -> AsArray a
max :: AsArray a -> AsArray a -> AsArray a
$cmax :: forall a. Ord a => AsArray a -> AsArray a -> AsArray a
>= :: AsArray a -> AsArray a -> Bool
$c>= :: forall a. Ord a => AsArray a -> AsArray a -> Bool
> :: AsArray a -> AsArray a -> Bool
$c> :: forall a. Ord a => AsArray a -> AsArray a -> Bool
<= :: AsArray a -> AsArray a -> Bool
$c<= :: forall a. Ord a => AsArray a -> AsArray a -> Bool
< :: AsArray a -> AsArray a -> Bool
$c< :: forall a. Ord a => AsArray a -> AsArray a -> Bool
compare :: AsArray a -> AsArray a -> Ordering
$ccompare :: forall a. Ord a => AsArray a -> AsArray a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (AsArray a)
Ord)

instance (IsSequence r, Flat (Element r)) => Flat (AsArray r) where
  size :: AsArray r -> Int -> Int
size (AsArray r
a) = r -> Int -> Int
forall mono.
(IsSequence mono, Flat (Element mono)) =>
mono -> Int -> Int
sizeSequence r
a
  encode :: AsArray r -> Encoding
encode (AsArray r
a) = r -> Encoding
forall mono.
(Flat (Element mono), MonoFoldable mono) =>
mono -> Encoding
encodeSequence r
a
  decode :: Get (AsArray r)
decode = r -> AsArray r
forall a. a -> AsArray a
AsArray (r -> AsArray r) -> Get r -> Get (AsArray r)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get r
forall b. (Flat (Element b), IsSequence b) => Get b
decodeSequence

-- |Calculate size of an instance of IsSequence as the sum:
-- * of the size of all the elements
-- * plus the size of the array constructors (1 byte every 255 elements plus one final byte)
sizeSequence
  :: (IsSequence mono, Flat (Element mono)) => mono -> NumBits -> NumBits
sizeSequence :: mono -> Int -> Int
sizeSequence mono
s Int
acc =
  let (Int
sz, Int
len) =
          ((Int, Int) -> Element mono -> (Int, Int))
-> (Int, Int) -> mono -> (Int, Int)
forall mono a.
MonoFoldable mono =>
(a -> Element mono -> a) -> a -> mono -> a
ofoldl' (\(Int
acc, Int
l) Element mono
e -> (Element mono -> Int -> Int
forall a. Flat a => a -> Int -> Int
size Element mono
e Int
acc, Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)) (Int
acc, Int
0 :: NumBits) mono
s
  in  Int
sz Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int
arrayBits Int
len
{-# INLINE sizeSequence #-}

-- TODO: check which one is faster
-- sizeSequence s acc = ofoldl' (flip size) acc s + arrayBits (olength s)

-- |Encode an instance of IsSequence, as an array
encodeSequence :: (Flat (Element mono), MonoFoldable mono) => mono -> Encoding
encodeSequence :: mono -> Encoding
encodeSequence = [Element mono] -> Encoding
forall a. Flat a => [a] -> Encoding
encodeArray ([Element mono] -> Encoding)
-> (mono -> [Element mono]) -> mono -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. mono -> [Element mono]
forall mono. MonoFoldable mono => mono -> [Element mono]
otoList
{-# INLINE encodeSequence #-}

-- |Decode an instance of IsSequence, as an array
decodeSequence :: (Flat (Element b), IsSequence b) => Get b
decodeSequence :: Get b
decodeSequence = [Element b] -> b
forall seq. IsSequence seq => [Element seq] -> seq
S.fromList ([Element b] -> b) -> Get [Element b] -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get (Element b) -> Get [Element b]
forall a. Get a -> Get [a]
decodeArrayWith Get (Element b)
forall a. Flat a => Get a
decode
{-# INLINE decodeSequence #-}

newtype AsList a =
  AsList
    { AsList a -> a
unList :: a
    } deriving (Int -> AsList a -> ShowS
[AsList a] -> ShowS
AsList a -> String
(Int -> AsList a -> ShowS)
-> (AsList a -> String) -> ([AsList a] -> ShowS) -> Show (AsList a)
forall a. Show a => Int -> AsList a -> ShowS
forall a. Show a => [AsList a] -> ShowS
forall a. Show a => AsList a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AsList a] -> ShowS
$cshowList :: forall a. Show a => [AsList a] -> ShowS
show :: AsList a -> String
$cshow :: forall a. Show a => AsList a -> String
showsPrec :: Int -> AsList a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> AsList a -> ShowS
Show,AsList a -> AsList a -> Bool
(AsList a -> AsList a -> Bool)
-> (AsList a -> AsList a -> Bool) -> Eq (AsList a)
forall a. Eq a => AsList a -> AsList a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AsList a -> AsList a -> Bool
$c/= :: forall a. Eq a => AsList a -> AsList a -> Bool
== :: AsList a -> AsList a -> Bool
$c== :: forall a. Eq a => AsList a -> AsList a -> Bool
Eq,Eq (AsList a)
Eq (AsList a)
-> (AsList a -> AsList a -> Ordering)
-> (AsList a -> AsList a -> Bool)
-> (AsList a -> AsList a -> Bool)
-> (AsList a -> AsList a -> Bool)
-> (AsList a -> AsList a -> Bool)
-> (AsList a -> AsList a -> AsList a)
-> (AsList a -> AsList a -> AsList a)
-> Ord (AsList a)
AsList a -> AsList a -> Bool
AsList a -> AsList a -> Ordering
AsList a -> AsList a -> AsList a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (AsList a)
forall a. Ord a => AsList a -> AsList a -> Bool
forall a. Ord a => AsList a -> AsList a -> Ordering
forall a. Ord a => AsList a -> AsList a -> AsList a
min :: AsList a -> AsList a -> AsList a
$cmin :: forall a. Ord a => AsList a -> AsList a -> AsList a
max :: AsList a -> AsList a -> AsList a
$cmax :: forall a. Ord a => AsList a -> AsList a -> AsList a
>= :: AsList a -> AsList a -> Bool
$c>= :: forall a. Ord a => AsList a -> AsList a -> Bool
> :: AsList a -> AsList a -> Bool
$c> :: forall a. Ord a => AsList a -> AsList a -> Bool
<= :: AsList a -> AsList a -> Bool
$c<= :: forall a. Ord a => AsList a -> AsList a -> Bool
< :: AsList a -> AsList a -> Bool
$c< :: forall a. Ord a => AsList a -> AsList a -> Bool
compare :: AsList a -> AsList a -> Ordering
$ccompare :: forall a. Ord a => AsList a -> AsList a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (AsList a)
Ord)

instance (IsSequence l, Flat (Element l)) => Flat (AsList l) where
  -- size   = sizeList . S.unpack . unList
  -- encode = encodeList . S.unpack . unList
  -- decode = AsList . S.fromList <$> decodeListotoList

  size :: AsList l -> Int -> Int
size   = l -> Int -> Int
forall mono.
(MonoFoldable mono, Flat (Element mono)) =>
mono -> Int -> Int
sizeList (l -> Int -> Int) -> (AsList l -> l) -> AsList l -> Int -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AsList l -> l
forall a. AsList a -> a
unList
  encode :: AsList l -> Encoding
encode = l -> Encoding
forall mono.
(Flat (Element mono), MonoFoldable mono) =>
mono -> Encoding
encodeList (l -> Encoding) -> (AsList l -> l) -> AsList l -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AsList l -> l
forall a. AsList a -> a
unList
  decode :: Get (AsList l)
decode = l -> AsList l
forall a. a -> AsList a
AsList (l -> AsList l) -> Get l -> Get (AsList l)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get l
forall b. (IsSequence b, Flat (Element b)) => Get b
decodeList

{-# INLINE sizeList #-}
sizeList
  :: (MonoFoldable mono, Flat (Element mono)) => mono -> NumBits -> NumBits
sizeList :: mono -> Int -> Int
sizeList mono
l Int
sz = (Int -> Element mono -> Int) -> Int -> mono -> Int
forall mono a.
MonoFoldable mono =>
(a -> Element mono -> a) -> a -> mono -> a
ofoldl' (\Int
s Element mono
e -> Element mono -> Int -> Int
forall a. Flat a => a -> Int -> Int
size Element mono
e (Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)) (Int
sz Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) mono
l

{-# INLINE encodeList #-}
encodeList :: (Flat (Element mono), MonoFoldable mono) => mono -> Encoding
encodeList :: mono -> Encoding
encodeList = (Element mono -> Encoding) -> [Element mono] -> Encoding
forall t. (t -> Encoding) -> [t] -> Encoding
encodeListWith Element mono -> Encoding
forall a. Flat a => a -> Encoding
encode ([Element mono] -> Encoding)
-> (mono -> [Element mono]) -> mono -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. mono -> [Element mono]
forall mono. MonoFoldable mono => mono -> [Element mono]
otoList

{-# INLINE decodeList #-}
decodeList :: (IsSequence b, Flat (Element b)) => Get b
decodeList :: Get b
decodeList = [Element b] -> b
forall seq. IsSequence seq => [Element seq] -> seq
S.fromList ([Element b] -> b) -> Get [Element b] -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get (Element b) -> Get [Element b]
forall a. Get a -> Get [a]
decodeListWith Get (Element b)
forall a. Flat a => Get a
decode

newtype AsSet a =
  AsSet
    { AsSet a -> a
unSet :: a
    } deriving (Int -> AsSet a -> ShowS
[AsSet a] -> ShowS
AsSet a -> String
(Int -> AsSet a -> ShowS)
-> (AsSet a -> String) -> ([AsSet a] -> ShowS) -> Show (AsSet a)
forall a. Show a => Int -> AsSet a -> ShowS
forall a. Show a => [AsSet a] -> ShowS
forall a. Show a => AsSet a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AsSet a] -> ShowS
$cshowList :: forall a. Show a => [AsSet a] -> ShowS
show :: AsSet a -> String
$cshow :: forall a. Show a => AsSet a -> String
showsPrec :: Int -> AsSet a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> AsSet a -> ShowS
Show,AsSet a -> AsSet a -> Bool
(AsSet a -> AsSet a -> Bool)
-> (AsSet a -> AsSet a -> Bool) -> Eq (AsSet a)
forall a. Eq a => AsSet a -> AsSet a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AsSet a -> AsSet a -> Bool
$c/= :: forall a. Eq a => AsSet a -> AsSet a -> Bool
== :: AsSet a -> AsSet a -> Bool
$c== :: forall a. Eq a => AsSet a -> AsSet a -> Bool
Eq,Eq (AsSet a)
Eq (AsSet a)
-> (AsSet a -> AsSet a -> Ordering)
-> (AsSet a -> AsSet a -> Bool)
-> (AsSet a -> AsSet a -> Bool)
-> (AsSet a -> AsSet a -> Bool)
-> (AsSet a -> AsSet a -> Bool)
-> (AsSet a -> AsSet a -> AsSet a)
-> (AsSet a -> AsSet a -> AsSet a)
-> Ord (AsSet a)
AsSet a -> AsSet a -> Bool
AsSet a -> AsSet a -> Ordering
AsSet a -> AsSet a -> AsSet a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (AsSet a)
forall a. Ord a => AsSet a -> AsSet a -> Bool
forall a. Ord a => AsSet a -> AsSet a -> Ordering
forall a. Ord a => AsSet a -> AsSet a -> AsSet a
min :: AsSet a -> AsSet a -> AsSet a
$cmin :: forall a. Ord a => AsSet a -> AsSet a -> AsSet a
max :: AsSet a -> AsSet a -> AsSet a
$cmax :: forall a. Ord a => AsSet a -> AsSet a -> AsSet a
>= :: AsSet a -> AsSet a -> Bool
$c>= :: forall a. Ord a => AsSet a -> AsSet a -> Bool
> :: AsSet a -> AsSet a -> Bool
$c> :: forall a. Ord a => AsSet a -> AsSet a -> Bool
<= :: AsSet a -> AsSet a -> Bool
$c<= :: forall a. Ord a => AsSet a -> AsSet a -> Bool
< :: AsSet a -> AsSet a -> Bool
$c< :: forall a. Ord a => AsSet a -> AsSet a -> Bool
compare :: AsSet a -> AsSet a -> Ordering
$ccompare :: forall a. Ord a => AsSet a -> AsSet a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (AsSet a)
Ord)

instance (IsSet set, Flat (Element set)) => Flat (AsSet set) where
  size :: AsSet set -> Int -> Int
size   = Size set
forall set. (IsSet set, Flat (Element set)) => Size set
sizeSet Size set -> (AsSet set -> set) -> AsSet set -> Int -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AsSet set -> set
forall a. AsSet a -> a
unSet
  encode :: AsSet set -> Encoding
encode = set -> Encoding
forall set. (IsSet set, Flat (Element set)) => set -> Encoding
encodeSet (set -> Encoding) -> (AsSet set -> set) -> AsSet set -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AsSet set -> set
forall a. AsSet a -> a
unSet
  decode :: Get (AsSet set)
decode = set -> AsSet set
forall a. a -> AsSet a
AsSet (set -> AsSet set) -> Get set -> Get (AsSet set)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get set
forall set. (IsSet set, Flat (Element set)) => Get set
decodeSet

sizeSet :: (IsSet set, Flat (Element set)) => Size set
sizeSet :: Size set
sizeSet set
l Int
acc = (Int -> Element set -> Int) -> Int -> set -> Int
forall mono a.
MonoFoldable mono =>
(a -> Element mono -> a) -> a -> mono -> a
ofoldl' (\Int
acc Element set
e -> ContainerKey set -> Int -> Int
forall a. Flat a => a -> Int -> Int
size ContainerKey set
Element set
e (Int
acc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)) (Int
acc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (set -> Int) -> set -> Int
forall a b. (a -> b) -> a -> b
$ set
l
{-# INLINE sizeSet #-}

encodeSet :: (IsSet set, Flat (Element set)) => set -> Encoding
encodeSet :: set -> Encoding
encodeSet = [ContainerKey set] -> Encoding
forall mono.
(Flat (Element mono), MonoFoldable mono) =>
mono -> Encoding
encodeList ([ContainerKey set] -> Encoding)
-> (set -> [ContainerKey set]) -> set -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. set -> [ContainerKey set]
forall set. IsSet set => set -> [Element set]
setToList
{-# INLINE encodeSet #-}

decodeSet :: (IsSet set, Flat (Element set)) => Get set
decodeSet :: Get set
decodeSet = [ContainerKey set] -> set
forall set. IsSet set => [Element set] -> set
setFromList ([ContainerKey set] -> set) -> Get [ContainerKey set] -> Get set
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get [ContainerKey set]
forall b. (IsSequence b, Flat (Element b)) => Get b
decodeList
{-# INLINE decodeSet #-}

{-|
Maps are saved as lists of (key,value) tuples.

>>> tst (AsMap (Data.Map.fromList ([]::[(Word8,())])))
(True,1,[0])

>>> tst (AsMap (Data.Map.fromList [(3::Word,9::Word)]))
(True,18,[129,132,128])
-}
newtype AsMap a =
  AsMap
    { AsMap a -> a
unMap :: a
    } deriving (Int -> AsMap a -> ShowS
[AsMap a] -> ShowS
AsMap a -> String
(Int -> AsMap a -> ShowS)
-> (AsMap a -> String) -> ([AsMap a] -> ShowS) -> Show (AsMap a)
forall a. Show a => Int -> AsMap a -> ShowS
forall a. Show a => [AsMap a] -> ShowS
forall a. Show a => AsMap a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AsMap a] -> ShowS
$cshowList :: forall a. Show a => [AsMap a] -> ShowS
show :: AsMap a -> String
$cshow :: forall a. Show a => AsMap a -> String
showsPrec :: Int -> AsMap a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> AsMap a -> ShowS
Show,AsMap a -> AsMap a -> Bool
(AsMap a -> AsMap a -> Bool)
-> (AsMap a -> AsMap a -> Bool) -> Eq (AsMap a)
forall a. Eq a => AsMap a -> AsMap a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AsMap a -> AsMap a -> Bool
$c/= :: forall a. Eq a => AsMap a -> AsMap a -> Bool
== :: AsMap a -> AsMap a -> Bool
$c== :: forall a. Eq a => AsMap a -> AsMap a -> Bool
Eq,Eq (AsMap a)
Eq (AsMap a)
-> (AsMap a -> AsMap a -> Ordering)
-> (AsMap a -> AsMap a -> Bool)
-> (AsMap a -> AsMap a -> Bool)
-> (AsMap a -> AsMap a -> Bool)
-> (AsMap a -> AsMap a -> Bool)
-> (AsMap a -> AsMap a -> AsMap a)
-> (AsMap a -> AsMap a -> AsMap a)
-> Ord (AsMap a)
AsMap a -> AsMap a -> Bool
AsMap a -> AsMap a -> Ordering
AsMap a -> AsMap a -> AsMap a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (AsMap a)
forall a. Ord a => AsMap a -> AsMap a -> Bool
forall a. Ord a => AsMap a -> AsMap a -> Ordering
forall a. Ord a => AsMap a -> AsMap a -> AsMap a
min :: AsMap a -> AsMap a -> AsMap a
$cmin :: forall a. Ord a => AsMap a -> AsMap a -> AsMap a
max :: AsMap a -> AsMap a -> AsMap a
$cmax :: forall a. Ord a => AsMap a -> AsMap a -> AsMap a
>= :: AsMap a -> AsMap a -> Bool
$c>= :: forall a. Ord a => AsMap a -> AsMap a -> Bool
> :: AsMap a -> AsMap a -> Bool
$c> :: forall a. Ord a => AsMap a -> AsMap a -> Bool
<= :: AsMap a -> AsMap a -> Bool
$c<= :: forall a. Ord a => AsMap a -> AsMap a -> Bool
< :: AsMap a -> AsMap a -> Bool
$c< :: forall a. Ord a => AsMap a -> AsMap a -> Bool
compare :: AsMap a -> AsMap a -> Ordering
$ccompare :: forall a. Ord a => AsMap a -> AsMap a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (AsMap a)
Ord)

instance (IsMap map, Flat (ContainerKey map), Flat (MapValue map)) => Flat (AsMap map) where
  size :: AsMap map -> Int -> Int
size   = Size map
forall r.
(Flat (ContainerKey r), Flat (MapValue r), IsMap r) =>
Size r
sizeMap Size map -> (AsMap map -> map) -> AsMap map -> Int -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AsMap map -> map
forall a. AsMap a -> a
unMap
  encode :: AsMap map -> Encoding
encode = map -> Encoding
forall map.
(Flat (ContainerKey map), Flat (MapValue map), IsMap map) =>
map -> Encoding
encodeMap (map -> Encoding) -> (AsMap map -> map) -> AsMap map -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AsMap map -> map
forall a. AsMap a -> a
unMap
  decode :: Get (AsMap map)
decode = map -> AsMap map
forall a. a -> AsMap a
AsMap (map -> AsMap map) -> Get map -> Get (AsMap map)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get map
forall map.
(Flat (ContainerKey map), Flat (MapValue map), IsMap map) =>
Get map
decodeMap

{-# INLINE sizeMap #-}
sizeMap :: (Flat (ContainerKey r), Flat (MapValue r), IsMap r) => Size r
sizeMap :: Size r
sizeMap r
m Int
acc =
  (Int -> (ContainerKey r, MapValue r) -> Int)
-> Int -> [(ContainerKey r, MapValue r)] -> Int
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' (\Int
acc' (ContainerKey r
k, MapValue r
v) -> ContainerKey r -> Int -> Int
forall a. Flat a => a -> Int -> Int
size ContainerKey r
k (MapValue r -> Int -> Int
forall a. Flat a => a -> Int -> Int
size MapValue r
v (Int
acc' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))) (Int
acc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
    ([(ContainerKey r, MapValue r)] -> Int)
-> (r -> [(ContainerKey r, MapValue r)]) -> r -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. r -> [(ContainerKey r, MapValue r)]
forall map. IsMap map => map -> [(ContainerKey map, MapValue map)]
mapToList
    (r -> Int) -> r -> Int
forall a b. (a -> b) -> a -> b
$ r
m
-- sizeMap l sz = ofoldl' (\s (k, v) -> size k (size v (s + 1))) (sz + 1) l

{-# INLINE encodeMap #-}
-- |Encode an instance of IsMap, as a list of (Key,Value) tuples
encodeMap
  :: (Flat (ContainerKey map), Flat (MapValue map), IsMap map)
  => map
  -> Encoding
encodeMap :: map -> Encoding
encodeMap = ((ContainerKey map, MapValue map) -> Encoding)
-> [(ContainerKey map, MapValue map)] -> Encoding
forall t. (t -> Encoding) -> [t] -> Encoding
encodeListWith (\(ContainerKey map
k, MapValue map
v) -> ContainerKey map -> Encoding
forall a. Flat a => a -> Encoding
encode ContainerKey map
k Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> MapValue map -> Encoding
forall a. Flat a => a -> Encoding
encode MapValue map
v) ([(ContainerKey map, MapValue map)] -> Encoding)
-> (map -> [(ContainerKey map, MapValue map)]) -> map -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. map -> [(ContainerKey map, MapValue map)]
forall map. IsMap map => map -> [(ContainerKey map, MapValue map)]
mapToList

{-# INLINE decodeMap #-}
-- |Decode an instance of IsMap, as a list of (Key,Value) tuples
decodeMap
  :: (Flat (ContainerKey map), Flat (MapValue map), IsMap map) => Get map
decodeMap :: Get map
decodeMap = [(ContainerKey map, MapValue map)] -> map
forall map. IsMap map => [(ContainerKey map, MapValue map)] -> map
mapFromList ([(ContainerKey map, MapValue map)] -> map)
-> Get [(ContainerKey map, MapValue map)] -> Get map
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get (ContainerKey map, MapValue map)
-> Get [(ContainerKey map, MapValue map)]
forall a. Get a -> Get [a]
decodeListWith ((,) (ContainerKey map
 -> MapValue map -> (ContainerKey map, MapValue map))
-> Get (ContainerKey map)
-> Get (MapValue map -> (ContainerKey map, MapValue map))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get (ContainerKey map)
forall a. Flat a => Get a
decode Get (MapValue map -> (ContainerKey map, MapValue map))
-> Get (MapValue map) -> Get (ContainerKey map, MapValue map)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get (MapValue map)
forall a. Flat a => Get a
decode)