packages feed

nbparts-0.1.0.0: src/Nbparts/Pack/Metadata.hs

module Nbparts.Pack.Metadata where

import Data.Ipynb qualified as Ipynb
import Data.Map (Map)
import Data.Map qualified as Map
import Data.Text (Text)
import Nbparts.Types
  ( CellMetadata (CodeCellMetadata, GenericCellMetadata),
    CellMetadataTag (CodeCellMetadataTag, GenericCellMetadataTag),
    NotebookMetadata (NotebookMetadata),
    PackError (PackCellMetadataTypeMismatch, PackMissingCellIdError, actual, expected),
    emptyCodeMetadata,
    emptyGenericMetadata,
  )

fillMetadata :: NotebookMetadata -> Ipynb.Notebook a -> Either PackError (Ipynb.Notebook a)
fillMetadata (NotebookMetadata formatMajor formatMinor nbMeta cellsMeta) (Ipynb.Notebook _ _ cells) =
  Ipynb.Notebook
    nbMeta
    (formatMajor, formatMinor)
    <$> filledCells
  where
    filledCells = traverse (fillCellMetadata cellsMeta) cells

fillCellMetadata :: Map Text CellMetadata -> Ipynb.Cell a -> Either PackError (Ipynb.Cell a)
fillCellMetadata metaMap (Ipynb.Cell cellType maybeCellId source _ attachments) = do
  cellId <- case maybeCellId of
    Just cId -> Right cId
    Nothing -> Left PackMissingCellIdError
  let cellMeta = case (Map.lookup cellId metaMap, cellType) of
        (Just meta, _) -> meta
        -- If we can't find the metadata, assume there is none.
        (Nothing, Ipynb.Code _ _) -> emptyCodeMetadata
        (Nothing, _) -> emptyGenericMetadata
  case (cellType, cellMeta) of
    -- Code cell expects CodeCellMetadata
    (Ipynb.Code _ outputs, CodeCellMetadata exeCount meta) ->
      Right $ Ipynb.Cell (Ipynb.Code exeCount outputs) (Just cellId) source meta attachments
    (Ipynb.Code _ _, GenericCellMetadata _) ->
      Left $
        PackCellMetadataTypeMismatch
          { expected = CodeCellMetadataTag,
            actual = GenericCellMetadataTag
          }
    -- Other cell types expect GenericCellMetadata
    (_, GenericCellMetadata meta) ->
      Right $ Ipynb.Cell cellType (Just cellId) source meta attachments
    (_, CodeCellMetadata _ _) ->
      Left $
        PackCellMetadataTypeMismatch
          { expected = GenericCellMetadataTag,
            actual = CodeCellMetadataTag
          }