{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
module Nix.Derivation.Parser
(
parseDerivation
, parseDerivationWith
, textParser
) where
import Data.Attoparsec.Text.Lazy (Parser)
import Data.Map (Map)
import Data.Set (Set)
import Data.Text (Text)
import Data.Vector (Vector)
import Nix.Derivation.Types (Derivation(..), DerivationOutput(..))
import qualified Data.Attoparsec.Text
import qualified Data.Attoparsec.Text.Lazy
import qualified Data.Map
import qualified Data.Set
import qualified Data.Text
import qualified Data.Vector
import qualified System.FilePath
listOf :: Parser a -> Parser [a]
listOf :: forall a. Parser a -> Parser [a]
listOf Parser a
element = do
Parser Text Text
"["
es <- Parser a -> Parser Text Text -> Parser Text [a]
forall (f :: * -> *) a s. Alternative f => f a -> f s -> f [a]
Data.Attoparsec.Text.Lazy.sepBy Parser a
element Parser Text Text
","
"]"
return es
parseDerivation :: Parser (Derivation FilePath Text)
parseDerivation :: Parser (Derivation String Text)
parseDerivation = Parser String
-> Parser Text Text -> Parser (Derivation String Text)
forall fp txt.
(Ord fp, Ord txt) =>
Parser fp -> Parser txt -> Parser (Derivation fp txt)
parseDerivationWith Parser String
filepathParser Parser Text Text
textParser
parseDerivationWith :: (Ord fp, Ord txt) => Parser fp -> Parser txt -> Parser (Derivation fp txt)
parseDerivationWith :: forall fp txt.
(Ord fp, Ord txt) =>
Parser fp -> Parser txt -> Parser (Derivation fp txt)
parseDerivationWith Parser fp
filepath Parser txt
string = do
Parser Text Text
"Derive("
let keyValue0 :: Parser Text (txt, DerivationOutput fp txt)
keyValue0 = do
Parser Text Text
"("
key <- Parser txt
string
","
path <- filepath
","
hashAlgo <- string
","
hash <- string
")"
return (key, DerivationOutput {..})
outputs <- Parser Text (txt, DerivationOutput fp txt)
-> Parser (Map txt (DerivationOutput fp txt))
forall k v. Ord k => Parser (k, v) -> Parser (Map k v)
mapOf Parser Text (txt, DerivationOutput fp txt)
keyValue0
","
let keyValue1 = do
Parser Text Text
"("
key <- Parser fp
filepath
","
value <- setOf string
")"
return (key, value)
inputDrvs <- mapOf keyValue1
","
inputSrcs <- setOf filepath
","
platform <- string
","
builder <- string
","
args <- vectorOf string
","
let keyValue2 = do
Parser Text Text
"("
key <- Parser txt
string
","
value <- string
")"
return (key, value)
env <- mapOf keyValue2
")"
return (Derivation {..})
textParser :: Parser Text
textParser :: Parser Text Text
textParser = do
Parser Text Text
"\""
let predicate :: Char -> Bool
predicate Char
c = Bool -> Bool
not (Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'"' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\\')
let loop :: Parser Text [Text]
loop = do
text0 <- (Char -> Bool) -> Parser Text Text
Data.Attoparsec.Text.takeWhile Char -> Bool
predicate
char0 <- Data.Attoparsec.Text.anyChar
case char0 of
Char
'"' -> do
[Text] -> Parser Text [Text]
forall a. a -> Parser Text a
forall (m :: * -> *) a. Monad m => a -> m a
return [ Text
text0 ]
Char
_ -> do
char1 <- Parser Char
Data.Attoparsec.Text.anyChar
char2 <- case char1 of
Char
'n' -> Char -> Parser Char
forall a. a -> Parser Text a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
'\n'
Char
'r' -> Char -> Parser Char
forall a. a -> Parser Text a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
'\r'
Char
't' -> Char -> Parser Char
forall a. a -> Parser Text a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
'\t'
Char
_ -> Char -> Parser Char
forall a. a -> Parser Text a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
char1
textChunks <- loop
return (text0 : Data.Text.singleton char2 : textChunks)
textChunks <- Parser Text [Text]
loop
return (Data.Text.concat textChunks)
filepathParser :: Parser FilePath
filepathParser :: Parser String
filepathParser = do
text <- Parser Text Text
textParser
let str = Text -> String
Data.Text.unpack Text
text
case (Data.Text.uncons text, System.FilePath.isValid str) of
(Just (Char
'/', Text
_), Bool
True) -> do
String -> Parser String
forall a. a -> Parser Text a
forall (m :: * -> *) a. Monad m => a -> m a
return String
str
(Maybe (Char, Text), Bool)
_ -> do
String -> Parser String
forall a. String -> Parser Text a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"bad path ‘" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
Data.Text.unpack Text
text String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"’ in derivation")
setOf :: Ord a => Parser a -> Parser (Set a)
setOf :: forall a. Ord a => Parser a -> Parser (Set a)
setOf Parser a
element = do
es <- Parser a -> Parser [a]
forall a. Parser a -> Parser [a]
listOf Parser a
element
return (Data.Set.fromList es)
vectorOf :: Parser a -> Parser (Vector a)
vectorOf :: forall a. Parser a -> Parser (Vector a)
vectorOf Parser a
element = do
es <- Parser a -> Parser [a]
forall a. Parser a -> Parser [a]
listOf Parser a
element
return (Data.Vector.fromList es)
mapOf :: Ord k => Parser (k, v) -> Parser (Map k v)
mapOf :: forall k v. Ord k => Parser (k, v) -> Parser (Map k v)
mapOf Parser (k, v)
keyValue = do
keyValues <- Parser (k, v) -> Parser [(k, v)]
forall a. Parser a -> Parser [a]
listOf Parser (k, v)
keyValue
return (Data.Map.fromList keyValues)