packages feed

import-style-plugin-0.1.0.0: src/ImportStylePlugin/Config.hs

{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}

module ImportStylePlugin.Config where

import Control.Applicative ((<|>))
import Data.Aeson (FromJSON (..), FromJSONKey, Value (..), withObject, (.:))
import qualified Data.Map.Strict as Map
import Data.Set (Set)
import Data.String (IsString)
import GHC.Generics (Generic)

-- | Report either error or warning during compilation
data Severity = Error | Warning
  deriving (Generic, FromJSON, Show)

data Qualification = Required | Forbidden
  deriving (Generic, FromJSON, Show)

data ModuleAliases = Exactly (Set String) | OrOmitted (Set String)
  deriving (Show)

data NamesList = BlackList (Set String) | WhiteList (Set String)
  deriving (Show)

data ImportRule = ImportRule
  { qualification :: Maybe Qualification
  -- ^ @'Nothing'@ means "don\'t care"
  , aliases :: Maybe ModuleAliases
  -- ^ @'Nothing'@ means "don\'t care"
  , importedNames :: Maybe NamesList
  -- ^ @'Nothing'@ means "don\'t care"
  }
  deriving (Generic, FromJSON, Show)

data QualificationStyle = Post | Pre
  deriving (Generic, FromJSON, Show)

data ImportRules = ImportRules
  { rules :: [ImportRule]
  , severity :: Severity
  }
  deriving (Generic, FromJSON, Show)

data Ban = Ban
  { severity :: Severity
  , why :: String
  -- ^ ban reason
  }
  deriving (Generic, FromJSON, Show)

data ImportsStyle
  = ImportsStyle
  { qualificationStyle :: Maybe QualificationStyle
  -- ^ @'Nothing'@ means "don\'t care"
  , bannedModules :: Map.Map ModuleName Ban
  , importRules :: Map.Map ModuleName ImportRules
  }
  deriving (Generic, FromJSON, Show)

newtype ModuleName = ModuleName String
  deriving (Eq, Ord)
  deriving newtype (FromJSONKey, IsString, Show)

instance FromJSON NamesList where
  parseJSON = withObject "NamesList" \o ->
    BlackList <$> o .: "blacklist" <|> WhiteList <$> o .: "whitelist"

instance FromJSON ModuleAliases where
  parseJSON (Object o) = Exactly <$> o .: "exactly"
  parseJSON o = OrOmitted <$> parseJSON o