Created
February 19, 2013 03:10
-
-
Save carlohamalainen/4982764 to your computer and use it in GitHub Desktop.
Uses Parsec to read the results of "nova list".
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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