nirum-0.4.0: src/Nirum/Targets/Python/Serializers.hs
{-# LANGUAGE QuasiQuotes #-}
module Nirum.Targets.Python.Serializers (compileSerializer) where
import Data.Text (replace)
import Text.InterpolatedString.Perl6 (q, qq)
import Nirum.Constructs.TypeDeclaration
import Nirum.Constructs.TypeExpression
import {-# SOURCE #-} Nirum.Targets.Python ()
import Nirum.Targets.Python.CodeGen
import Nirum.TypeInstance.BoundModule
compileSerializer :: BoundModule Python -> TypeExpression -> Code -> Code
compileSerializer mod' (OptionModifier typeExpr) pythonVar =
[qq|(None if ($pythonVar) is None
else ({compileSerializer mod' typeExpr pythonVar}))|]
compileSerializer mod' (SetModifier typeExpr) pythonVar =
compileSerializer mod' (ListModifier typeExpr) pythonVar
compileSerializer mod' (ListModifier typeExpr) pythonVar =
[qq|list(($serializer) for $elemVar in ($pythonVar))|]
where
elemVar :: Code
elemVar = mangleVar pythonVar "elem"
serializer :: Code
serializer = compileSerializer mod' typeExpr elemVar
compileSerializer mod' (MapModifier kt vt) pythonVar =
[qq|list(
\{
'key': ({compileSerializer mod' kt kVar}),
'value': ({compileSerializer mod' vt vVar}),
\}
for $kVar, $vVar in ($pythonVar).items()
)|]
where
kVar :: Code
kVar = mangleVar pythonVar "key"
vVar :: Code
vVar = mangleVar pythonVar "value"
compileSerializer mod' (TypeIdentifier typeId) pythonVar =
case lookupType typeId mod' of
Missing -> "None" -- must never happen
Local (Alias t) -> compileSerializer mod' t pythonVar
Imported modulePath' _ (Alias t) ->
case resolveBoundModule modulePath' (boundPackage mod') of
Nothing -> "None" -- must never happen
Just foundMod -> compileSerializer foundMod t pythonVar
Local PrimitiveType { primitiveTypeIdentifier = p } ->
compilePrimitiveTypeSerializer p pythonVar
Imported _ _ PrimitiveType { primitiveTypeIdentifier = p } ->
compilePrimitiveTypeSerializer p pythonVar
Local EnumType {} -> serializerCall
Imported _ _ EnumType {} -> serializerCall
Local RecordType {} -> serializerCall
Imported _ _ RecordType {} -> serializerCall
Local UnboxedType {} -> serializerCall
Imported _ _ UnboxedType {} -> serializerCall
Local UnionType {} -> serializerCall
Imported _ _ UnionType {} -> serializerCall
where
serializerCall :: Code
serializerCall = [qq|$pythonVar.__nirum_serialize__()|]
compilePrimitiveTypeSerializer :: PrimitiveTypeIdentifier -> Code -> Code
compilePrimitiveTypeSerializer Bigint var = var
compilePrimitiveTypeSerializer Decimal var = [qq|str($var)|]
compilePrimitiveTypeSerializer Int32 var = var
compilePrimitiveTypeSerializer Int64 var = var
compilePrimitiveTypeSerializer Float32 var = var
compilePrimitiveTypeSerializer Float64 var = var
compilePrimitiveTypeSerializer Text var = var
compilePrimitiveTypeSerializer Binary var =
[qq|__import__('base64').b64encode($var).decode('ascii')|]
compilePrimitiveTypeSerializer Date var = [qq|($var).isoformat()|]
compilePrimitiveTypeSerializer Datetime var = replace "$var" var [q|(
'{0}-{1:02}-{2:02}T{3:02}:{4:02}:{5:02}'.format(
*($var).utctimetuple()
) +
('.{0:06}'.format(($var).microsecond) if ($var).microsecond else '') +
'Z'
)|]
compilePrimitiveTypeSerializer Bool var = var
compilePrimitiveTypeSerializer Uuid var = [qq|str($var).lower()|]
compilePrimitiveTypeSerializer Url var = var