module Bytezap.Write.Derived where

import Bytezap.Write.Internal
import Bytezap.Poke.Derived qualified as Poke

import Data.ByteString.Short qualified as SBS
import Data.Text.Internal qualified as T
import Data.Char ( ord )

-- | Write a 'SBS.ShortByteString'.
shortByteString :: SBS.ShortByteString -> Write ExactLength s
shortByteString :: forall s. ShortByteString -> Write 'ExactLength s
shortByteString ShortByteString
sbs = Int -> Poke s -> Write 'ExactLength s
forall (lt :: LengthType) s. Int -> Poke s -> Write lt s
Write (ShortByteString -> Int
SBS.length ShortByteString
sbs) (ShortByteString -> Poke s
forall s. ShortByteString -> Poke s
Poke.shortByteString ShortByteString
sbs)

-- | Write a 'T.Text'.
text :: T.Text -> Write ExactLength s
text :: forall s. Text -> Write 'ExactLength s
text t :: Text
t@(T.Text Array
_arr Int
_off Int
len) = Int -> Poke s -> Write 'ExactLength s
forall (lt :: LengthType) s. Int -> Poke s -> Write lt s
Write Int
len (Text -> Poke s
forall s. Text -> Poke s
Poke.text Text
t)

-- | Write a 'Char'.
--
-- Adapted from utf8-string.
char :: Char -> Write ExactLength s
char :: forall s. Char -> Write 'ExactLength s
char Char
c = Int -> Poke s -> Write 'ExactLength s
forall (lt :: LengthType) s. Int -> Poke s -> Write lt s
Write (Int -> Int
forall {a} {a}. (Ord a, Num a, Num a) => a -> a
go (Char -> Int
ord Char
c)) (Char -> Poke s
forall s. Char -> Poke s
Poke.char Char
c)
 where
  go :: a -> a
go a
oc
   | a
oc a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
0x7f       = a
1
   | a
oc a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
0x7ff      = a
2
   | a
oc a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
0xffff     = a
3
   | Bool
otherwise        = a
4