emanote-1.2.0.0: src/Emanote/Model/Meta.hs
module Emanote.Model.Meta (
lookupRouteMeta,
getEffectiveRouteMeta,
getEffectiveRouteMetaWith,
) where
import Data.Aeson (FromJSON)
import Data.Aeson qualified as Aeson
import Data.IxSet.Typed qualified as Ix
import Emanote.Model (ModelT, modelLookupNoteByRoute', modelSData)
import Emanote.Model.Note (_noteMeta)
import Emanote.Model.SData (sdataValue)
import Emanote.Model.SData qualified as SData
import Emanote.Route qualified as R
import Optics.Operators as Lens ((^.))
import Relude
-- | Look up a specific key in the meta for a given route.
lookupRouteMeta :: (FromJSON a) => a -> NonEmpty Text -> R.LMLRoute -> ModelT f -> a
lookupRouteMeta x k r =
SData.lookupAeson x k . getEffectiveRouteMeta r
{- | Get the (final) metadata of a note at the given route, by merging it with
the defaults specified in parent routes all the way upto index.yaml.
-}
getEffectiveRouteMeta :: R.LMLRoute -> ModelT f -> Aeson.Value
getEffectiveRouteMeta mr model =
let mNote = modelLookupNoteByRoute' mr model
in getEffectiveRouteMetaWith (maybe Aeson.Null _noteMeta mNote) mr model
getEffectiveRouteMetaWith :: Aeson.Value -> R.LMLRoute -> ModelT f -> Aeson.Value
getEffectiveRouteMetaWith frontmatter mr model =
let defaultFiles = R.routeInits @'R.Yaml (R.withLmlRoute coerce mr)
defaults = flip mapMaybe (toList defaultFiles) $ \r -> do
v <- getYamlMeta r model
guard $ v /= Aeson.Null
pure v
metas = defaults <> maybe mempty one (guard (frontmatter /= Aeson.Null) >> pure frontmatter)
in maybe Aeson.Null SData.mergeAesons $ nonEmpty metas
getYamlMeta :: R.R 'R.Yaml -> ModelT f -> Maybe Aeson.Value
getYamlMeta r model =
fmap (^. sdataValue) . Ix.getOne . Ix.getEQ r $ model ^. modelSData