domain-0.1.1.5: library/Domain/YamlUnscrambler/TypeCentricDoc.hs
module Domain.YamlUnscrambler.TypeCentricDoc where
import qualified Control.Foldl as Fold
import qualified Data.Text as Text
import qualified Domain.Attoparsec.General as GeneralAttoparsec
import qualified Domain.Attoparsec.TypeString as TypeStringAttoparsec
import Domain.Models.TypeCentricDoc
import qualified Domain.Models.TypeString as TypeStringModel
import Domain.Prelude
import YamlUnscrambler
doc :: Value [(Text, Structure)]
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 Structure
structure =
value [] (Just structureMapping) Nothing
byFieldName :: Value val -> Value [(Text, val)]
byFieldName onElement =
value onScalar (Just onMapping) Nothing
where
onScalar =
[nullScalar []]
onMapping =
foldMapping (,) Fold.list textString onElement
sumTypeExpression :: Value [NestedTypeExpression]
sumTypeExpression =
value onScalar (Just onMapping) (Just onSequence)
where
onScalar =
[ nullScalar [],
fmap (fmap AppSeqNestedTypeExpression)
$ stringScalar
$ attoparsedString "Type signature"
$ GeneralAttoparsec.only TypeStringAttoparsec.commaSeq
]
onMapping =
pure . StructureNestedTypeExpression <$> structureMapping
onSequence =
foldSequence Fold.list nestedTypeExpression
nestedTypeExpression :: Value NestedTypeExpression
nestedTypeExpression =
value [onScalar] (Just onMapping) Nothing
where
onScalar =
AppSeqNestedTypeExpression <$> appTypeStringScalar
onMapping =
StructureNestedTypeExpression <$> structureMapping
enumVariants :: Value [Text]
enumVariants =
sequenceValue (foldSequence Fold.list variant)
where
variant =
scalarsValue [stringScalar textString]
-- * Scalar
-------------------------
appTypeStringScalar :: Scalar (NonEmpty TypeStringModel.Unit)
appTypeStringScalar =
stringScalar
$ attoparsedString "Type signature"
$ GeneralAttoparsec.only TypeStringAttoparsec.appSeq
-- * Mapping
-------------------------
structureMapping :: Mapping Structure
structureMapping =
byKeyMapping (CaseSensitive True)
$ atByKey "product" (ProductStructure <$> byFieldName nestedTypeExpression)
<|> atByKey "sum" (SumStructure <$> byFieldName sumTypeExpression)
<|> atByKey "enum" (EnumStructure <$> enumVariants)