pgrep-0.1.0.0: src/Scrappy/Grep/Output.hs
module Scrappy.Grep.Output
( formatResult
, formatResults
, OutputFormat(..)
) where
import Scrappy.Grep.DSL (MatchResult(..))
import Data.List (intercalate)
data OutputFormat
= FormatGrep -- file:line:col:match
| FormatVerbose -- file:line:col: match (with context)
| FormatJSON -- JSON output
| FormatCount -- Just count of matches
deriving (Show, Eq)
-- | Format a single match result
formatResult :: OutputFormat -> MatchResult -> String
formatResult fmt mr = case fmt of
FormatGrep ->
mrFilePath mr ++ ":" ++
show (mrLine mr) ++ ":" ++
show (mrCol mr) ++ ":" ++
escapeNewlines (mrMatchText mr)
FormatVerbose ->
mrFilePath mr ++ ":" ++
show (mrLine mr) ++ ":" ++
show (mrCol mr) ++ ": " ++
mrMatchText mr
FormatJSON ->
"{\"file\":\"" ++ escapeJSON (mrFilePath mr) ++
"\",\"line\":" ++ show (mrLine mr) ++
",\"col\":" ++ show (mrCol mr) ++
",\"match\":\"" ++ escapeJSON (mrMatchText mr) ++ "\"}"
FormatCount -> ""
-- | Format multiple results
formatResults :: OutputFormat -> [MatchResult] -> String
formatResults FormatCount results =
show (length results) ++ " match" ++ (if length results == 1 then "" else "es")
formatResults FormatJSON results =
"[" ++ intercalate "," (map (formatResult FormatJSON) results) ++ "]"
formatResults fmt results =
unlines $ map (formatResult fmt) results
-- | Escape newlines for single-line output
escapeNewlines :: String -> String
escapeNewlines = concatMap escape
where
escape '\n' = "\\n"
escape '\t' = "\\t"
escape '\r' = "\\r"
escape c = [c]
-- | Escape for JSON strings
escapeJSON :: String -> String
escapeJSON = concatMap escape
where
escape '"' = "\\\""
escape '\\' = "\\\\"
escape '\n' = "\\n"
escape '\t' = "\\t"
escape '\r' = "\\r"
escape c = [c]