Skip to content

Instantly share code, notes, and snippets.

@Gabriella439
Created January 7, 2021 01:32
Show Gist options
  • Save Gabriella439/e9617cef45c77be256039c96152b63be to your computer and use it in GitHub Desktop.
Save Gabriella439/e9617cef45c77be256039c96152b63be to your computer and use it in GitHub Desktop.
CSV decoding example
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
module Main where
import Data.Csv (FromField, FromNamedRecord)
import Data.Text (Text)
import Data.Map (Map)
import Data.Vector (Vector)
import GHC.Generics (Generic)
import qualified Data.ByteString.Lazy as ByteString
import qualified Data.Csv as Csv
import qualified Data.List as List
import qualified Data.Text as Text
import qualified Data.Vector as Vector
import qualified Text.Show.Pretty as Pretty
data Row = Row
{ device_name :: Text
, device_ip :: Text
, type_ :: Text
, os :: Maybe OperatingSystem
, os_version :: Maybe Text
, activity_count :: Text
, first_seen :: Text
, last_seen :: Text
, duration :: Text
, risk_score :: Double
, mpid :: Integer
} deriving (Generic, Show)
instance FromNamedRecord Row where
parseNamedRecord =
Csv.genericParseNamedRecord Csv.defaultOptions{
Csv.fieldLabelModifier =
reverse . dropWhile (\c -> c == '_') . reverse
}
data OperatingSystem
= Windows
| OSX
| Ubuntu
| Linux
| Debian
| Undetermined
| IOS
| Android
| Apple
| RIMOS
| CellOS
| PlayStation
| ChromeOS
deriving (Show)
instance FromField OperatingSystem where
parseField s = case s of
"Windows" -> pure Windows
"Mac OS X" -> pure OSX
"Ubuntu Linux" -> pure Ubuntu
"Linux" -> pure Linux
"Debian Linux" -> pure Debian
"Undetermined" -> pure Undetermined
"iOS" -> pure IOS
"Android" -> pure Android
"Apple" -> pure Apple
"RIM OS" -> pure RIMOS
"Cell OS" -> pure CellOS
"PlayStation" -> pure PlayStation
"Chrome OS" -> pure ChromeOS
_ -> fail "Unrecognized operating system"
main :: IO ()
main = do
bytes <- ByteString.readFile "./device_results.csv"
case Csv.decodeByName @Row bytes of
Left string -> fail string
Right (_header, rows) -> do
Pretty.pPrint (Vector.take 10 rows)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment