content: module String where
  
  import Data.ByteString (ByteString)
  import qualified Data.ByteString as B
  import qualified Data.ByteString.Char8 as BC
  import qualified Data.ByteString.Short as SB
  import Data.Word (Word64)
  
  
  newTraceIdFromHeader :: ByteString -> SB.ShortByteString
  newTraceIdFromHeader = SB.toShort . fillLeadingZeros 16 . convertWord64ToBinaryByteString . read . BC.unpack
  
  
  newSpanIdFromHeader :: ByteString -> SB.ShortByteString
  newSpanIdFromHeader = SB.toShort . fillLeadingZeros 8 . convertWord64ToBinaryByteString . read . BC.unpack
  
  
  newHeaderFromTraceId :: SB.ShortByteString -> ByteString
  newHeaderFromTraceId = BC.pack . show . convertBinaryByteStringToWord64 . SB.fromShort
  
  
  newHeaderFromSpanId :: SB.ShortByteString -> ByteString
  newHeaderFromSpanId = BC.pack . show . convertBinaryByteStringToWord64 . SB.fromShort
  
  
  convertWord64ToBinaryByteString :: Word64 -> ByteString
  convertWord64ToBinaryByteString =
    B.pack . toWord8s []
    where
      toWord8s acc 0 = acc
      toWord8s acc n =
        let (p, q) = n `divMod` (2 ^ (8 :: Int))
        in toWord8s (fromIntegral q : acc) p
  
  
  fillLeadingZeros :: Word -> ByteString -> ByteString
  fillLeadingZeros len bs = B.replicate (fromIntegral len - B.length bs) 0 <> bs
  
  
  convertBinaryByteStringToWord64 :: ByteString -> Word64
  convertBinaryByteStringToWord64 = B.foldl (\acc b -> (2 ^ (8 :: Int)) * acc + fromIntegral b) 0 -- GHC.Prim.indexWord8ArrayAsWord64# とか駆使すると早くなりそう
  