Skip to content

Instantly share code, notes, and snippets.

@carlohamalainen
Created February 19, 2013 03:10
Show Gist options
  • Save carlohamalainen/4982764 to your computer and use it in GitHub Desktop.
Save carlohamalainen/4982764 to your computer and use it in GitHub Desktop.
Uses Parsec to read the results of "nova list".
import Control.Applicative hiding ((<|>),many)
import Control.Monad
import Control.Monad.State
import Text.Parsec
import Text.Parsec.String
import Data.Functor.Identity
import Safe (headMay)
data Network = Network { networkCell :: String
, networkIP :: String
} deriving (Show)
data Status = Active | Building | Unknown | StatusError String deriving (Show)
sToStatus :: String -> Status
sToStatus "ACTIVE" = Active
sToStatus "BUILD" = Building
sToStatus "UNKNOWN" = Unknown
sToStatus s = StatusError s
strip = lstrip . rstrip
lstrip = dropWhile (`elem` " \t")
rstrip = reverse . lstrip . reverse
delimeter :: ParsecT String u Data.Functor.Identity.Identity (Char)
delimeter = do
char '+'
many (char '-')
char '+'
many (char '-')
char '+'
many (char '-')
char '+'
many (char '-')
char '+'
header :: ParsecT String u Data.Functor.Identity.Identity (Char)
header = do
char '|'
spaces
string "ID"
spaces
char '|'
spaces
string "Name"
spaces
char '|'
spaces
string "Status"
spaces
char '|'
spaces
string "Networks"
spaces
char '|'
networkInfo :: ParsecT String u Data.Functor.Identity.Identity (Maybe Network)
networkInfo = do
location <- many (noneOf "=\n")
char '='
ip <- many (noneOf " \n")
return $ Just $ Network location ip
statusLine :: ParsecT String u Data.Functor.Identity.Identity ((String, String, Status, Maybe Network))
statusLine = do
char '|'
spaces
hash <- many (noneOf " ")
spaces
char '|'
spaces
name <- rstrip <$> (many (noneOf "|"))
spaces
char '|'
spaces
state <- sToStatus <$> (many (noneOf " "))
spaces
char '|'
spaces
net <- try (networkInfo <* spaces <* char '|') <|> (spaces >> char '|' >> (return Nothing))
return (hash, name, state, net)
list = do
delimeter
newline
header
newline
delimeter
newline
lines <- manyTill (statusLine <* newline) (delimeter >> newline)
return lines
main = do
raw <- getContents
let x = parse list "" raw
case x of (Right result) -> forM_ result print
(Left err) -> print err
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment