neuron-1.0.0.0: src/lib/Neuron/Config/Type.hs
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Neuron.Config.Type
( Config (..),
configFile,
defaultConfig,
mergeWithDefault,
getZettelFormats,
getSiteBaseUrl,
)
where
import Data.Aeson
import Neuron.Reader.Type (ZettelFormat)
import Relude hiding (readEither)
import Text.Read (readEither)
import Text.URI (URI, mkURI)
configFile :: FilePath
configFile = "neuron.dhall"
-- | Config type for @neuron.dhall@
--
-- See <https://neuron.zettel.page/configuration.html guide> for description of the fields.
--
-- TODO: Implement custom `FromDhall` instance, while using original field types
data Config = Config
{ aliases :: [Text],
author :: Maybe Text,
editUrl :: Maybe Text,
-- TODO: This should use `NonEmpty`.
formats :: [Text],
minVersion :: Text,
siteBaseUrl :: Maybe Text,
siteTitle :: Text,
theme :: Text
}
deriving (Eq, Show, Generic, FromJSON, ToJSON)
getZettelFormats :: MonadFail m => Config -> m (NonEmpty ZettelFormat)
getZettelFormats Config {..} = do
formats' <- maybe (fail "Empty formats") pure $ nonEmpty formats
traverse (either (fail . toString) pure . readEither . toString) formats'
getSiteBaseUrl :: MonadFail m => Config -> m (Maybe URI)
getSiteBaseUrl Config {..} =
runMaybeT $ do
s <- MaybeT $ pure siteBaseUrl
case mkURI s of
Left e ->
fail $ displayException e
Right uri ->
pure uri
defaultConfig :: Text
defaultConfig =
"{ siteTitle =\
\ \"My Zettelkasten\" \
\, author =\
\ None Text\
\, siteBaseUrl =\
\ None Text\
\, editUrl =\
\ None Text\
\, theme =\
\ \"blue\"\
\, aliases =\
\ [] : List Text\
\, formats =\
\ [ \"markdown\" ]\
\, minVersion =\
\ \"0.5\" \
\}"
-- Dhall's combine operator (`//`) allows us to merge two records,
-- effectively merging the record with defaults with the user record.
mergeWithDefault :: Text -> Text
mergeWithDefault userConfig =
defaultConfig <> " // " <> userConfig