packages feed

cfn-flip-0.1.0.6: src/CfnFlip/YamlToJson.hs

module CfnFlip.YamlToJson
  ( InvalidYamlEvent (..)
  , translate
  ) where

import CfnFlip.Prelude
import qualified Prelude as Unsafe (toEnum)

import CfnFlip.Conduit
import CfnFlip.IntrinsicFunction
import CfnFlip.Libyaml
import qualified Data.ByteString as BS

translate :: MonadIO m => ConduitT Event Event m ()
translate = awaitForever $ \case
  e@(EventScalar x (UriTag "!GetAtt") _ _) -> do
    (resource, attribute) <- maybe (throwInvalidGetAtt e x) pure $ parseGetAtt x

    makeMapping "Fn::GetAtt"
      $ makeSequence
      $ yieldMany
        [ EventScalar resource NoTag Plain Nothing
        , EventScalar attribute NoTag Plain Nothing
        ]
  e | Just tag <- getIntrinsicFunction e -> do
    makeMapping tag $ do
      yield e
      when (startsMapOrSequence e) $ takeMapOrSequenceC e .| translate
  e -> yield e

parseGetAtt :: ByteString -> Maybe (ByteString, ByteString)
parseGetAtt x = case BS.split (charToWord8 '.') x of
  [resource, attribute] -> Just (resource, attribute)
  _ -> Nothing

throwInvalidGetAtt :: MonadIO m => Event -> ByteString -> m a
throwInvalidGetAtt e x =
  throwIO
    $ InvalidYamlEvent e
    $ "!GetAtt shoule be \"Resource.Attribute\", saw "
      <> show x

charToWord8 :: Char -> Word8
charToWord8 = Unsafe.toEnum . fromEnum