packages feed

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

-- | Module      : IPLD.DagCBOR.Encoder.CID
--   Description : Implements encoding CIDs within DAG-CBOR
--   Copyright   : Zoey McBride (c) 2026
--   License     : AGPL-3.0-or-later
--   Maintainer  : zoeymcbride@mailbox.org
--   Stability   : experimental
module IPLD.DagCBOR.Encoder.CID
  ( -- * DAG-CBOR CID encoder implementation
    encodeResourceKind,

    -- * CBOR tag major id
    majorTag,
  )
where

import Data.ByteString.Builder (Builder)
import Data.ByteString.Builder qualified as Builder
import IPLD.DagCBOR.Encoder.Arguments
import IPLD.DagCBOR.Encoder.Errors
import IPLD.DagCBOR.Encoder.Ints
import IPLD.DagCBOR.Encoder.Strings
import MultiFormats.CID (CID)
import MultiFormats.CID qualified as CID
import MultiFormats.CID.Constants qualified as CID
import MultiFormats.CID.Serializer qualified as CID

-- | Major id for tagged CBOR objects.
majorTag :: MajorArg
majorTag = 6

-- | Implements encoding CID data into DAG-CBOR.
encodeResourceKind :: CID -> Okay Builder
encodeResourceKind resource = cbortag <<>> bytesobj <<>> ciddata
  where
    -- Encodes the CBOR tag identifying IPLD CIDs
    cbortag = encodeIntArgument majorTag CID.ipldTagCBOR
    -- Encodes the #bytes + the single byte for the identity multibase
    bytesobj = encodeIntArgument majorBytes (CID.cidSizeOf resource + 1)
    -- Encodes the CID within its own Okay functor
    cidserial = CID.serializer resource
    -- Encodes required the identity multibase byte
    cidmultibase = Builder.word8 0
    -- Encodes the CID or wraps the given error
    ciddata = either (Left . CIDError) (Right . (cidmultibase <>)) cidserial