module Language.Docker.Parser.Expose ( parseExpose, ) where import qualified Data.Text as T import Language.Docker.Parser.Prelude import Language.Docker.Syntax parseExpose :: (?esc :: Char) => Parser (Instruction Text) parseExpose :: (?esc::Char) => Parser (Instruction Text) parseExpose = do (?esc::Char) => Text -> Parser () reserved Text "EXPOSE" forall args. Ports -> Instruction args Expose forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> (?esc::Char) => Parser Ports ports ports :: (?esc :: Char) => Parser Ports ports :: (?esc::Char) => Parser Ports ports = [PortSpec] -> Ports Ports forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> (?esc::Char) => Parser PortSpec portspec forall (m :: * -> *) a sep. MonadPlus m => m a -> m sep -> m [a] `sepEndBy` (?esc::Char) => Parser () requiredWhitespace portspec :: (?esc :: Char) => Parser PortSpec portspec :: (?esc::Char) => Parser PortSpec portspec = ( forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a try (?esc::Char) => Parser PortSpec parsePortRangeSpec forall e s (m :: * -> *) a. MonadParsec e s m => m a -> String -> m a <?> String "A range of ports optionally followed by the protocol" ) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a <|> ( (?esc::Char) => Parser PortSpec parsePortSpec forall e s (m :: * -> *) a. MonadParsec e s m => m a -> String -> m a <?> String "A port optionally followed by the protocol" ) parsePortRangeSpec :: (?esc :: Char) => Parser PortSpec parsePortRangeSpec :: (?esc::Char) => Parser PortSpec parsePortRangeSpec = PortRange -> PortSpec PortRangeSpec forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> (?esc::Char) => Parser PortRange portRange parsePortSpec :: (?esc :: Char) => Parser PortSpec parsePortSpec :: (?esc::Char) => Parser PortSpec parsePortSpec = Port -> PortSpec PortSpec forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> (?esc::Char) => Parser Port port port :: (?esc :: Char) => Parser Port port :: (?esc::Char) => Parser Port port = (forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a try (?esc::Char) => Parser Port portVariable forall e s (m :: * -> *) a. MonadParsec e s m => m a -> String -> m a <?> String "a variable") forall (f :: * -> *) a. Alternative f => f a -> f a -> f a <|> (forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a try Parser Port portWithProtocol forall e s (m :: * -> *) a. MonadParsec e s m => m a -> String -> m a <?> String "a port with its protocol (udp/tcp)") forall (f :: * -> *) a. Alternative f => f a -> f a -> f a <|> (Parser Port portInt forall e s (m :: * -> *) a. MonadParsec e s m => m a -> String -> m a <?> String "a valid port number") portRangeLimit :: (?esc :: Char) => Parser Port portRangeLimit :: (?esc::Char) => Parser Port portRangeLimit = Parser Port number forall (f :: * -> *) a. Alternative f => f a -> f a -> f a <|> Parser Port variable where number :: Parser Port number = do Integer num <- Parser Integer natural forall (m :: * -> *) a. Monad m => a -> m a return forall a b. (a -> b) -> a -> b $ Int -> Protocol -> Port Port (forall a b. (Integral a, Num b) => a -> b fromIntegral Integer num) Protocol TCP variable :: Parser Port variable = do forall (f :: * -> *) a. Functor f => f a -> f () void (forall e s (m :: * -> *). (MonadParsec e s m, Token s ~ Char) => Token s -> m (Token s) char Char '$') Text var <- (?esc::Char) => String -> (Char -> Bool) -> Parser Text someUnless String "the variable name" (\Char c -> Char c forall a. Eq a => a -> a -> Bool == Char '-' Bool -> Bool -> Bool || Char c forall a. Eq a => a -> a -> Bool == Char '/') forall (m :: * -> *) a. Monad m => a -> m a return forall a b. (a -> b) -> a -> b $ Text -> Port PortStr (Text -> Text -> Text T.append Text "$" Text var) portRange :: (?esc :: Char) => Parser PortRange portRange :: (?esc::Char) => Parser PortRange portRange = do Port start <- (?esc::Char) => Parser Port portRangeLimit forall (f :: * -> *) a. Functor f => f a -> f () void forall a b. (a -> b) -> a -> b $ forall e s (m :: * -> *). (MonadParsec e s m, Token s ~ Char) => Token s -> m (Token s) char Char '-' Port finish <- forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a try (?esc::Char) => Parser Port portRangeLimit Protocol proto <- forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a try ParsecT DockerfileError Text Identity Protocol protocol forall (f :: * -> *) a. Alternative f => f a -> f a -> f a <|> forall (m :: * -> *) a. Monad m => a -> m a return Protocol TCP forall (m :: * -> *) a. Monad m => a -> m a return forall a b. (a -> b) -> a -> b $ Port -> Port -> PortRange PortRange (Port -> Protocol -> Port setProto Port start Protocol proto) (Port -> Protocol -> Port setProto Port finish Protocol proto) where setProto :: Port -> Protocol -> Port setProto :: Port -> Protocol -> Port setProto (Port Int p Protocol _) Protocol prot = Int -> Protocol -> Port Port Int p Protocol prot setProto (PortStr Text s) Protocol _ = Text -> Port PortStr Text s protocol :: Parser Protocol protocol :: ParsecT DockerfileError Text Identity Protocol protocol = do forall (f :: * -> *) a. Functor f => f a -> f () void (forall e s (m :: * -> *). (MonadParsec e s m, Token s ~ Char) => Token s -> m (Token s) char Char '/') forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a try (ParsecT DockerfileError Text Identity Protocol tcp forall (f :: * -> *) a. Alternative f => f a -> f a -> f a <|> ParsecT DockerfileError Text Identity Protocol udp) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a <|> forall (m :: * -> *) a. MonadFail m => String -> m a fail String "invalid protocol" where tcp :: ParsecT DockerfileError Text Identity Protocol tcp = Text -> Parser Text caseInsensitiveString Text "tcp" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> forall (m :: * -> *) a. Monad m => a -> m a return Protocol TCP udp :: ParsecT DockerfileError Text Identity Protocol udp = Text -> Parser Text caseInsensitiveString Text "udp" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> forall (m :: * -> *) a. Monad m => a -> m a return Protocol UDP portInt :: Parser Port portInt :: Parser Port portInt = do Integer portNumber <- Parser Integer natural forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m () notFollowedBy (forall e s (m :: * -> *). MonadParsec e s m => Tokens s -> m (Tokens s) string Tokens Text "/" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a <|> forall e s (m :: * -> *). MonadParsec e s m => Tokens s -> m (Tokens s) string Tokens Text "-") forall (m :: * -> *) a. Monad m => a -> m a return forall a b. (a -> b) -> a -> b $ Int -> Protocol -> Port Port (forall a b. (Integral a, Num b) => a -> b fromIntegral Integer portNumber) Protocol TCP portWithProtocol :: Parser Port portWithProtocol :: Parser Port portWithProtocol = do Integer portNumber <- Parser Integer natural Int -> Protocol -> Port Port (forall a b. (Integral a, Num b) => a -> b fromIntegral Integer portNumber) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> ParsecT DockerfileError Text Identity Protocol protocol portVariable :: (?esc :: Char) => Parser Port portVariable :: (?esc::Char) => Parser Port portVariable = do forall (f :: * -> *) a. Functor f => f a -> f () void (forall e s (m :: * -> *). (MonadParsec e s m, Token s ~ Char) => Token s -> m (Token s) char Char '$') Text variable <- (?esc::Char) => String -> (Char -> Bool) -> Parser Text someUnless String "the variable name" (forall a. Eq a => a -> a -> Bool == Char '$') forall (m :: * -> *) a. Monad m => a -> m a return forall a b. (a -> b) -> a -> b $ Text -> Port PortStr (Text -> Text -> Text T.append Text "$" Text variable)