-- | Sized vectors.

{-# LANGUAGE NoStarIsType #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

module Binrep.Type.Vector where

import Binrep
import Data.Vector.Sized qualified as V
import Data.Vector.Sized ( Vector )
import GHC.TypeNats

type instance CBLen (Vector n a) = CBLen a * n

instance BLen a => BLen (Vector n a) where
    blen :: Vector n a -> BLenT
blen = Vector n BLenT -> BLenT
forall a (n :: Nat). Num a => Vector n a -> a
V.sum (Vector n BLenT -> BLenT)
-> (Vector n a -> Vector n BLenT) -> Vector n a -> BLenT
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> BLenT) -> Vector n a -> Vector n BLenT
forall a b (n :: Nat). (a -> b) -> Vector n a -> Vector n b
V.map a -> BLenT
forall a. BLen a => a -> BLenT
blen

instance Put a => Put (Vector n a) where
    put :: Vector n a -> Builder
put = [Builder] -> Builder
forall a. Monoid a => [a] -> a
mconcat ([Builder] -> Builder)
-> (Vector n a -> [Builder]) -> Vector n a -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector n Builder -> [Builder]
forall (n :: Nat) a. Vector n a -> [a]
V.toList (Vector n Builder -> [Builder])
-> (Vector n a -> Vector n Builder) -> Vector n a -> [Builder]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Builder) -> Vector n a -> Vector n Builder
forall a b (n :: Nat). (a -> b) -> Vector n a -> Vector n b
V.map a -> Builder
forall a. Put a => a -> Builder
put

instance (Get a, KnownNat n) => Get (Vector n a) where
    get :: Getter (Vector n a)
get = Getter a -> Getter (Vector n a)
forall (n :: Nat) a. KnownNat n => Getter a -> Getter (Vector n a)
getVector Getter a
forall a. Get a => Getter a
get

getVector :: KnownNat n => Getter a -> Getter (Vector n a)
getVector :: forall (n :: Nat) a. KnownNat n => Getter a -> Getter (Vector n a)
getVector Getter a
g = Getter a -> Parser String (Vector n a)
forall (n :: Nat) (m :: Type -> Type) a.
(KnownNat n, Monad m) =>
m a -> m (Vector n a)
V.replicateM Getter a
g