packages feed

ipldm-1.0.0.0: dagcbor/IPLD/DagCBOR/Encoder/Floats.hs

-- | Module      : IPLD.DagCBOR.Encoder.Floats
--   Description : Implements encoders for float simple types in DAG-CBOR
--   Copyright   : Zoey McBride (c) 2026
--   License     : AGPL-3.0-or-later
--   Maintainer  : zoeymcbride@mailbox.org
--   Stability   : experimental
module IPLD.DagCBOR.Encoder.Floats
  ( -- * CBOR floating point encoders
    encodeFloatKind,

    -- * Constants for working with CBOR floats
    paramDouble,
    paramSingle,
    paramHalf,
  )
where

import Data.ByteString.Builder (Builder)
import Data.ByteString.Builder qualified as BSB
import IPLD.DM qualified as DM
import IPLD.DagCBOR.Encoder.Arguments
import IPLD.DagCBOR.Encoder.SimpleTypes (majorSimple)

-- | Parameter for encoding 64-bit IEEE754 double precision data.
paramDouble :: ParamArg
paramDouble = 27

-- | Parameter for encoding 32-bit IEEE754 single precision data.
paramSingle :: ParamArg
paramSingle = 26

-- | Parameter for encoding 16-bit IEEE754 half precision data.
paramHalf :: ParamArg
paramHalf = 25

-- TODO:
-- encodeFloat :: forall bxc. (BinaryTranscoder bxc) => Float -> bxc
-- encodeDouble :: forall bxc. (BinaryTranscoder bxc) => Double -> bxc
-- NOTE: the encoder does no validation currently.

-- | Encodes a float from IPLD floating data.
{-# INLINE encodeFloatKind #-}
encodeFloatKind :: DM.FloatData -> Builder
encodeFloatKind (DM.DoublePrecision double) =
  -- Encodes 64-bit IEEE754 to CBOR simple doubles
  let arg64 = encodeArgument majorSimple paramDouble
   in arg64 <> BSB.word64BE double
encodeFloatKind (DM.SinglePrecision single) =
  -- Encodes 32-bit IEEE754 to CBOR simple floats
  let arg32 = encodeArgument majorSimple paramSingle
   in arg32 <> BSB.word32BE single
encodeFloatKind (DM.HalfPrecision half) =
  -- Encodes 16-bit IEEE754 to CBOR simple halfs
  let arg16 = encodeArgument majorSimple paramHalf
   in arg16 <> BSB.word16BE half