packages feed

keiro-dsl-0.10.0.0: src/Keiro/Dsl/RuntimePackage.hs

-- | Explicit Cabal package identity for the service runtime that compiles
-- generated Keiro modules.
module Keiro.Dsl.RuntimePackage
  ( RuntimePackageName (..),
    mkRuntimePackageName,
    isCabalPackageName,
  )
where

import Data.Char (isAscii, isDigit, isLetter)
import Data.Text (Text)
import Data.Text qualified as T

-- | A package name accepted by Cabal's component grammar. Keiro keeps this
-- distinct from a service name because the two identities need not agree.
newtype RuntimePackageName = RuntimePackageName
  { unRuntimePackageName :: Text
  }
  deriving stock (Eq, Ord, Show)

-- | Validate and construct an explicit runtime package name.
mkRuntimePackageName :: Text -> Either Text RuntimePackageName
mkRuntimePackageName packageName
  | isCabalPackageName packageName = Right (RuntimePackageName packageName)
  | otherwise = Left ("runtime package '" <> packageName <> "' does not follow Cabal package-name grammar")

-- | The package-name rule shared by mapped Haskell sources and the runtime
-- package setting. Every hyphen-separated component is non-empty, contains
-- only ASCII letters and digits, and contains at least one letter.
isCabalPackageName :: Text -> Bool
isCabalPackageName packageName =
  not (null components) && all validComponent components
  where
    components = T.splitOn "-" packageName
    validComponent component =
      not (T.null component)
        && T.all asciiAlphaNum component
        && T.any asciiLetter component
    asciiAlphaNum c = isAscii c && (isLetter c || isDigit c)
    asciiLetter c = isAscii c && isLetter c