{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}

module Data.Bytes.Builder.Bounded.Class
  ( ToBoundedBuilder (..)
  ) where

import Data.Int
import Data.Word

import qualified Data.Bytes.Builder.Bounded as Bounded
import qualified GHC.TypeNats as GHC

{- | Variant of To that can be encoded as a builder. Human-readable encodings
are used when possible. For example, numbers are encoded an ascii-encoded
decimal characters. UTF-8 is preferred for textual types. For types
that represent arbitrary bytes (e.g. Bytes, ByteString), the bytes
are preserved.

The goal of this typeclass is to reduce the size of builders produced
by quasiquotation.
-}
class ToBoundedBuilder a where
  type BoundedBuilderLength a :: GHC.Nat
  toBuilder :: a -> Bounded.Builder (BoundedBuilderLength a)

-- | Identity
instance ToBoundedBuilder (Bounded.Builder n) where
  type BoundedBuilderLength (Bounded.Builder n) = n
  toBuilder :: Builder n -> Builder (BoundedBuilderLength (Builder n))
toBuilder = Builder n -> Builder n
Builder n -> Builder (BoundedBuilderLength (Builder n))
forall a. a -> a
id

-- | Uses @int64Dec@.
instance ToBoundedBuilder Int64 where
  type BoundedBuilderLength Int64 = 20
  toBuilder :: Int64 -> Builder (BoundedBuilderLength Int64)
toBuilder = Int64 -> Builder 20
Int64 -> Builder (BoundedBuilderLength Int64)
Bounded.int64Dec

-- | Uses @int32Dec@.
instance ToBoundedBuilder Int32 where
  type BoundedBuilderLength Int32 = 11
  toBuilder :: Int32 -> Builder (BoundedBuilderLength Int32)
toBuilder = Int32 -> Builder 11
Int32 -> Builder (BoundedBuilderLength Int32)
Bounded.int32Dec

-- | Uses @int16Dec@.
instance ToBoundedBuilder Int16 where
  type BoundedBuilderLength Int16 = 6
  toBuilder :: Int16 -> Builder (BoundedBuilderLength Int16)
toBuilder = Int16 -> Builder 6
Int16 -> Builder (BoundedBuilderLength Int16)
Bounded.int16Dec

-- | Uses @int8Dec@.
instance ToBoundedBuilder Int8 where
  type BoundedBuilderLength Int8 = 4
  toBuilder :: Int8 -> Builder (BoundedBuilderLength Int8)
toBuilder = Int8 -> Builder 4
Int8 -> Builder (BoundedBuilderLength Int8)
Bounded.int8Dec

-- | Uses @intDec@.
instance ToBoundedBuilder Int where
  type BoundedBuilderLength Int = 20
  toBuilder :: Int -> Builder (BoundedBuilderLength Int)
toBuilder = Int -> Builder 20
Int -> Builder (BoundedBuilderLength Int)
Bounded.intDec

-- | Uses @word64Dec@.
instance ToBoundedBuilder Word64 where
  type BoundedBuilderLength Word64 = 19
  toBuilder :: Word64 -> Builder (BoundedBuilderLength Word64)
toBuilder = Word64 -> Builder 19
Word64 -> Builder (BoundedBuilderLength Word64)
Bounded.word64Dec

-- | Uses @word32Dec@.
instance ToBoundedBuilder Word32 where
  type BoundedBuilderLength Word32 = 10
  toBuilder :: Word32 -> Builder (BoundedBuilderLength Word32)
toBuilder = Word32 -> Builder 10
Word32 -> Builder (BoundedBuilderLength Word32)
Bounded.word32Dec

-- | Uses @word16Dec@.
instance ToBoundedBuilder Word16 where
  type BoundedBuilderLength Word16 = 5
  toBuilder :: Word16 -> Builder (BoundedBuilderLength Word16)
toBuilder = Word16 -> Builder 5
Word16 -> Builder (BoundedBuilderLength Word16)
Bounded.word16Dec

-- | Uses @word8Dec@.
instance ToBoundedBuilder Word8 where
  type BoundedBuilderLength Word8 = 3
  toBuilder :: Word8 -> Builder (BoundedBuilderLength Word8)
toBuilder = Word8 -> Builder 3
Word8 -> Builder (BoundedBuilderLength Word8)
Bounded.word8Dec

-- | Uses @wordDec@.
instance ToBoundedBuilder Word where
  type BoundedBuilderLength Word = 19
  toBuilder :: Word -> Builder (BoundedBuilderLength Word)
toBuilder = Word -> Builder 19
Word -> Builder (BoundedBuilderLength Word)
Bounded.wordDec