1
1
mirror of https://github.com/github/semantic.git synced 2024-12-23 14:54:16 +03:00
semantic/src/Renderer.hs

73 lines
2.7 KiB
Haskell
Raw Normal View History

2016-08-22 04:51:48 +03:00
module Renderer (Renderer, DiffArguments(..), Output(..), concatOutputs, toSummaryKey, Format(..)) where
2016-08-22 17:32:43 +03:00
import Data.Aeson (Value, toEncoding)
2016-08-10 19:17:23 +03:00
import Data.Aeson.Encoding (encodingToLazyByteString)
import Data.Functor.Both
2016-08-24 21:30:29 +03:00
import Data.Map as Map hiding (null)
import Data.Text as T (intercalate)
import Diff
import Prologue
import Source (SourceBlob)
import Syntax
2016-07-29 19:24:12 +03:00
-- | A function that will render a diff, given the two source blobs.
type Renderer annotation = Both SourceBlob -> Diff (Syntax Text) annotation -> Output
2016-04-01 22:34:52 +03:00
data DiffArguments = DiffArguments { format :: Format, output :: Maybe FilePath, outputPath :: FilePath }
2016-04-12 20:10:24 +03:00
deriving (Show)
2016-04-01 22:34:52 +03:00
-- | The available types of diff rendering.
data Format = Split | Patch | JSON | Summary
deriving (Show)
2016-09-01 00:57:32 +03:00
data Output = SplitOutput Text | PatchOutput Text | JSONOutput (Map Text Value) | SummaryOutput (Map Text (Map Text [Text]))
2016-08-22 16:27:13 +03:00
deriving (Show)
2016-08-22 04:51:48 +03:00
2016-08-24 21:30:29 +03:00
-- Returns a key representing the filename. If the filenames are different,
-- return 'before -> after'.
2016-08-22 04:51:48 +03:00
toSummaryKey :: Both FilePath -> Text
toSummaryKey = runBothWith $ \before after ->
2016-08-24 21:30:29 +03:00
toS $ case (before, after) of
("", after) -> after
(before, "") -> before
(before, after) | before == after -> after
(before, after) | not (null before) && not (null after) -> before <> " -> " <> after
(_, _) -> mempty
2016-08-24 21:16:01 +03:00
-- Concatenates a list of 'Output' depending on the output type.
-- For JSON, each file output is merged since they're uniquely keyed by filename.
-- For Summaries, each file output is merged into one 'Object' consisting of lists of
-- changes and errors.
-- Split and Patch output is appended together with newlines.
2016-08-10 19:17:23 +03:00
concatOutputs :: [Output] -> Text
2016-08-22 04:51:48 +03:00
concatOutputs list | isJSON list = toS . encodingToLazyByteString . toEncoding $ concatJSON list
where
concatJSON :: [Output] -> Map Text Value
concatJSON (JSONOutput hash : rest) = Map.union hash (concatJSON rest)
concatJSON _ = mempty
2016-08-22 04:51:48 +03:00
concatOutputs list | isSummary list = toS . encodingToLazyByteString . toEncoding $ concatSummaries list
where
2016-08-25 00:07:43 +03:00
concatSummaries :: [Output] -> Map Text (Map Text [Text])
concatSummaries (SummaryOutput hash : rest) = Map.unionWith (Map.unionWith (<>)) hash (concatSummaries rest)
concatSummaries _ = mempty
2016-08-22 04:51:48 +03:00
concatOutputs list | isText list = T.intercalate "\n" (toText <$> list)
concatOutputs _ = mempty
isJSON :: [Output] -> Bool
isJSON (JSONOutput _ : _) = True
isJSON _ = False
isSummary :: [Output] -> Bool
isSummary (SummaryOutput _ : _) = True
isSummary _ = False
isText :: [Output] -> Bool
isText (SplitOutput _ : _) = True
isText (PatchOutput _ : _) = True
isText _ = False
2016-08-10 19:17:23 +03:00
toText :: Output -> Text
toText (SplitOutput text) = text
toText (PatchOutput text) = text
toText _ = mempty