module Stan.Inspection
(
Inspection (..)
, categoryL
, descriptionL
, solutionL
, severityL
, analysisL
, InspectionAnalysis (..)
, InspectionsMap
, sortById
, prettyShowInspection
, prettyShowInspectionShort
, inspectionsMd
) where
import Relude.Extra.Lens (Lens', lens)
import Colourista (blue, bold, formatWith, green)
import Colourista.Short (b, i)
import Data.Aeson.Micro (ToJSON (..), object, (.=))
import Stan.Category (Category (..), prettyShowCategory)
import Stan.Core.Id (Id (..))
import Stan.Pattern.Ast (PatternAst)
import Stan.Severity (Severity, prettyShowSeverity)
import qualified Data.HashMap.Strict as HM
import qualified Data.Text as T
data Inspection = Inspection
{ Inspection -> Id Inspection
inspectionId :: !(Id Inspection)
, Inspection -> Text
inspectionName :: !Text
, Inspection -> Text
inspectionDescription :: !Text
, Inspection -> [Text]
inspectionSolution :: ![Text]
, Inspection -> NonEmpty Category
inspectionCategory :: !(NonEmpty Category)
, Inspection -> Severity
inspectionSeverity :: !Severity
, Inspection -> InspectionAnalysis
inspectionAnalysis :: !InspectionAnalysis
} deriving stock (Int -> Inspection -> ShowS
[Inspection] -> ShowS
Inspection -> String
(Int -> Inspection -> ShowS)
-> (Inspection -> String)
-> ([Inspection] -> ShowS)
-> Show Inspection
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Inspection] -> ShowS
$cshowList :: [Inspection] -> ShowS
show :: Inspection -> String
$cshow :: Inspection -> String
showsPrec :: Int -> Inspection -> ShowS
$cshowsPrec :: Int -> Inspection -> ShowS
Show, Inspection -> Inspection -> Bool
(Inspection -> Inspection -> Bool)
-> (Inspection -> Inspection -> Bool) -> Eq Inspection
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Inspection -> Inspection -> Bool
$c/= :: Inspection -> Inspection -> Bool
== :: Inspection -> Inspection -> Bool
$c== :: Inspection -> Inspection -> Bool
Eq)
instance ToJSON Inspection where
toJSON :: Inspection -> Value
toJSON Inspection{..} = [Pair] -> Value
object
[ "id" Text -> Id Inspection -> Pair
forall v. ToJSON v => Text -> v -> Pair
.= Id Inspection
inspectionId
, "name" Text -> Text -> Pair
forall v. ToJSON v => Text -> v -> Pair
.= Text
inspectionName
, "description" Text -> Text -> Pair
forall v. ToJSON v => Text -> v -> Pair
.= Text
inspectionDescription
, "solution" Text -> [Text] -> Pair
forall v. ToJSON v => Text -> v -> Pair
.= [Text]
inspectionSolution
, "category" Text -> [Category] -> Pair
forall v. ToJSON v => Text -> v -> Pair
.= NonEmpty Category -> [Category]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty Category
inspectionCategory
, "severity" Text -> Severity -> Pair
forall v. ToJSON v => Text -> v -> Pair
.= Severity
inspectionSeverity
]
descriptionL :: Lens' Inspection Text
descriptionL :: (Text -> f Text) -> Inspection -> f Inspection
descriptionL = (Inspection -> Text)
-> (Inspection -> Text -> Inspection) -> Lens' Inspection Text
forall s a. (s -> a) -> (s -> a -> s) -> Lens' s a
lens
Inspection -> Text
inspectionDescription
(\inspection :: Inspection
inspection new :: Text
new -> Inspection
inspection { inspectionDescription :: Text
inspectionDescription = Text
new })
solutionL :: Lens' Inspection [Text]
solutionL :: ([Text] -> f [Text]) -> Inspection -> f Inspection
solutionL = (Inspection -> [Text])
-> (Inspection -> [Text] -> Inspection) -> Lens' Inspection [Text]
forall s a. (s -> a) -> (s -> a -> s) -> Lens' s a
lens
Inspection -> [Text]
inspectionSolution
(\inspection :: Inspection
inspection new :: [Text]
new -> Inspection
inspection { inspectionSolution :: [Text]
inspectionSolution = [Text]
new })
categoryL :: Lens' Inspection (NonEmpty Category)
categoryL :: (NonEmpty Category -> f (NonEmpty Category))
-> Inspection -> f Inspection
categoryL = (Inspection -> NonEmpty Category)
-> (Inspection -> NonEmpty Category -> Inspection)
-> Lens' Inspection (NonEmpty Category)
forall s a. (s -> a) -> (s -> a -> s) -> Lens' s a
lens
Inspection -> NonEmpty Category
inspectionCategory
(\inspection :: Inspection
inspection new :: NonEmpty Category
new -> Inspection
inspection { inspectionCategory :: NonEmpty Category
inspectionCategory = NonEmpty Category
new })
severityL :: Lens' Inspection Severity
severityL :: (Severity -> f Severity) -> Inspection -> f Inspection
severityL = (Inspection -> Severity)
-> (Inspection -> Severity -> Inspection)
-> Lens' Inspection Severity
forall s a. (s -> a) -> (s -> a -> s) -> Lens' s a
lens
Inspection -> Severity
inspectionSeverity
(\inspection :: Inspection
inspection new :: Severity
new -> Inspection
inspection { inspectionSeverity :: Severity
inspectionSeverity = Severity
new })
analysisL :: Lens' Inspection InspectionAnalysis
analysisL :: (InspectionAnalysis -> f InspectionAnalysis)
-> Inspection -> f Inspection
analysisL = (Inspection -> InspectionAnalysis)
-> (Inspection -> InspectionAnalysis -> Inspection)
-> Lens' Inspection InspectionAnalysis
forall s a. (s -> a) -> (s -> a -> s) -> Lens' s a
lens
Inspection -> InspectionAnalysis
inspectionAnalysis
(\inspection :: Inspection
inspection new :: InspectionAnalysis
new -> Inspection
inspection { inspectionAnalysis :: InspectionAnalysis
inspectionAnalysis = InspectionAnalysis
new })
type InspectionsMap = HashMap (Id Inspection) Inspection
sortById :: InspectionsMap -> [Inspection]
sortById :: InspectionsMap -> [Inspection]
sortById = (Inspection -> Id Inspection) -> [Inspection] -> [Inspection]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortWith Inspection -> Id Inspection
inspectionId ([Inspection] -> [Inspection])
-> (InspectionsMap -> [Inspection])
-> InspectionsMap
-> [Inspection]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InspectionsMap -> [Inspection]
forall k v. HashMap k v -> [v]
HM.elems
data InspectionAnalysis
= FindAst !PatternAst
| Infix
| LazyField
| BigTuples
| PatternMatchOn_
| UseCompare
deriving stock (Int -> InspectionAnalysis -> ShowS
[InspectionAnalysis] -> ShowS
InspectionAnalysis -> String
(Int -> InspectionAnalysis -> ShowS)
-> (InspectionAnalysis -> String)
-> ([InspectionAnalysis] -> ShowS)
-> Show InspectionAnalysis
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [InspectionAnalysis] -> ShowS
$cshowList :: [InspectionAnalysis] -> ShowS
show :: InspectionAnalysis -> String
$cshow :: InspectionAnalysis -> String
showsPrec :: Int -> InspectionAnalysis -> ShowS
$cshowsPrec :: Int -> InspectionAnalysis -> ShowS
Show, InspectionAnalysis -> InspectionAnalysis -> Bool
(InspectionAnalysis -> InspectionAnalysis -> Bool)
-> (InspectionAnalysis -> InspectionAnalysis -> Bool)
-> Eq InspectionAnalysis
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: InspectionAnalysis -> InspectionAnalysis -> Bool
$c/= :: InspectionAnalysis -> InspectionAnalysis -> Bool
== :: InspectionAnalysis -> InspectionAnalysis -> Bool
$c== :: InspectionAnalysis -> InspectionAnalysis -> Bool
Eq)
prettyShowInspection :: Inspection -> Text
prettyShowInspection :: Inspection -> Text
prettyShowInspection Inspection{..} = [Text] -> Text
forall t. IsText t "unlines" => [t] -> t
unlines ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$
[ Text -> Text
forall str. (IsString str, Semigroup str) => str -> str
b "~~~STAN INSPECTION~~~"
, ""
, Text -> Text
forall str. (IsString str, Semigroup str) => str -> str
i " ✲ ID: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
forall str. (IsString str, Semigroup str) => str -> str
b (Id Inspection -> Text
forall a. Id a -> Text
unId Id Inspection
inspectionId)
, Text -> Text
forall str. (IsString str, Semigroup str) => str -> str
i " ✲ Name: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
inspectionName
, Text -> Text
forall str. (IsString str, Semigroup str) => str -> str
i " ✲ Description: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
inspectionDescription
, Text -> Text
forall str. (IsString str, Semigroup str) => str -> str
i " ✲ Severity: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Severity -> Text
prettyShowSeverity Severity
inspectionSeverity
, Text -> Text
forall str. (IsString str, Semigroup str) => str -> str
i " ✲ Category: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> [Text] -> Text
T.intercalate " " ((Category -> Text) -> [Category] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Category -> Text
prettyShowCategory ([Category] -> [Text]) -> [Category] -> [Text]
forall a b. (a -> b) -> a -> b
$ NonEmpty Category -> [Category]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty Category
inspectionCategory)
, ""
, [Text] -> Text -> Text
forall str. (IsString str, Semigroup str) => [str] -> str -> str
formatWith [Text
forall str. IsString str => str
green] "Possible solutions:"
] [Text] -> [Text] -> [Text]
forall a. Semigroup a => a -> a -> a
<> (Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (" - " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) [Text]
inspectionSolution
prettyShowInspectionShort :: Inspection -> Text
prettyShowInspectionShort :: Inspection -> Text
prettyShowInspectionShort Inspection{..} =
" ❋ "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Text] -> Text -> Text
forall str. (IsString str, Semigroup str) => [str] -> str -> str
formatWith [Text
forall str. IsString str => str
bold, Text
forall str. IsString str => str
blue] ("[" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Id Inspection -> Text
forall a. Id a -> Text
unId Id Inspection
inspectionId Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "] ")
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
forall str. (IsString str, Semigroup str) => str -> str
i Text
inspectionName
inspectionsMd :: [Inspection] -> Text
inspectionsMd :: [Inspection] -> Text
inspectionsMd inss :: [Inspection]
inss = Text
intro Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
toc Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Text] -> Text
forall t. IsText t "unlines" => [t] -> t
unlines ((Inspection -> Text) -> [Inspection] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Inspection -> Text
inspectionToMd [Inspection]
inss)
where
intro :: Text
intro :: Text
intro = "This document contains information about all inspections used in Stan to find observations in your projects. Below you can see more details about each inspection individually\n\n"
toc :: Text
toc :: Text
toc = "## Table of all Inspections\n\n" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Text] -> Text
forall t. IsText t "unlines" => [t] -> t
unlines ((Inspection -> Text) -> [Inspection] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Inspection -> Text
insLink [Inspection]
inss) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "\n"
insLink :: Inspection -> Text
insLink :: Inspection -> Text
insLink (Id Inspection -> Text
forall a. Id a -> Text
unId (Id Inspection -> Text)
-> (Inspection -> Id Inspection) -> Inspection -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Inspection -> Id Inspection
inspectionId -> Text
ins)= " * [" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
ins Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "](#" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
ins Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> ")"
inspectionToMd :: Inspection -> Text
inspectionToMd :: Inspection -> Text
inspectionToMd Inspection{..} = [Text] -> Text
forall t. IsText t "unlines" => [t] -> t
unlines ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$
[ "## " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Id Inspection -> Text
forall a. Id a -> Text
unId Id Inspection
inspectionId
, ""
, "[[Back to the Table of all Inspections] ↑](#table-of-all-inspections)"
, ""
, "| Property | Value |"
, "|--|--|"
, "| ID | " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Id Inspection -> Text
forall a. Id a -> Text
unId Id Inspection
inspectionId Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> " |"
, "| Name | " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
inspectionName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> " |"
, "| Description | " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
inspectionDescription Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> " |"
, "| Severity | " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Severity -> Text
forall b a. (Show a, IsString b) => a -> b
show Severity
inspectionSeverity Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> " |"
, "| Category | " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "#" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> [Text] -> Text
T.intercalate " #" ((Category -> Text) -> [Category] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Category -> Text
unCategory ([Category] -> [Text]) -> [Category] -> [Text]
forall a b. (a -> b) -> a -> b
$ NonEmpty Category -> [Category]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty Category
inspectionCategory) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> " |"
, ""
, "#### Possible solutions for " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Id Inspection -> Text
forall a. Id a -> Text
unId Id Inspection
inspectionId
] [Text] -> [Text] -> [Text]
forall a. Semigroup a => a -> a -> a
<> (Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (" - " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) [Text]
inspectionSolution