packages feed

domain-0.1: library/Domain/YamlUnscrambler/TypeCentricDoc.hs

module Domain.YamlUnscrambler.TypeCentricDoc
where

import Domain.Prelude
import Domain.Models.TypeCentricDoc
import YamlUnscrambler
import qualified Domain.Attoparsec.TypeString as TypeStringAttoparsec
import qualified Domain.Attoparsec.General as GeneralAttoparsec
import qualified Control.Foldl as Fold
import qualified Data.Text as Text


doc =
  value onScalar (Just onMapping) Nothing
  where
    onScalar =
      [nullScalar []]
    onMapping =
      foldMapping (,) Fold.list typeNameString structure
      where
        typeNameString =
          formattedString "type name" $ \ input ->
            case Text.uncons input of
              Just (h, t) ->
                if isUpper h
                  then
                    if Text.all (\ a -> isAlphaNum a || a == '\'' || a == '_') t
                      then
                        Right input
                      else
                        Left "Contains invalid chars"
                  else
                    Left "First char is not upper-case"
              Nothing ->
                Left "Empty string"

structure =
  value [] (Just onMapping) Nothing
  where
    onMapping =
      byKeyMapping (CaseSensitive True) $
        atByKey "product" (ProductStructure <$> byFieldName appTypeString) <|>
        atByKey "sum" (SumStructure <$> byFieldName sumTypeExpression) <|>
        atByKey "enum" (EnumStructure <$> enumVariants)

byFieldName onElement =
  value onScalar (Just onMapping) Nothing
  where
    onScalar =
      [nullScalar []]
    onMapping =
      foldMapping (,) Fold.list textString onElement

appTypeString =
  value [
    stringScalar $ attoparsedString "Type signature" $
    GeneralAttoparsec.only TypeStringAttoparsec.appSeq
    ] Nothing Nothing

sumTypeExpression =
  value onScalar Nothing (Just onSequence)
  where
    onScalar =
      [
        nullScalar (SequenceSumTypeExpression [])
        ,
        fmap StringSumTypeExpression $
        stringScalar $ attoparsedString "Type signature" $
        GeneralAttoparsec.only TypeStringAttoparsec.commaSeq
        ]
    onSequence =
      SequenceSumTypeExpression <$> foldSequence Fold.list appTypeString

enumVariants =
  sequenceValue (foldSequence Fold.list variant)
  where
    variant =
      scalarsValue [stringScalar textString]