packages feed

hydra-ext-0.17.0: src/main/haskell/Hydra/Rust/Serde.hs

-- Note: this is an automatically generated file. Do not edit.
-- | Rust serializer: converts Rust AST to concrete syntax

module Hydra.Rust.Serde where
import qualified Hydra.Ast as Ast
import qualified Hydra.Coders as Coders
import qualified Hydra.Constants as Constants
import qualified Hydra.Core as Core
import qualified Hydra.Error.Checking as Checking
import qualified Hydra.Error.Core as ErrorCore
import qualified Hydra.Error.Packaging as ErrorPackaging
import qualified Hydra.Errors as Errors
import qualified Hydra.Graph as Graph
import qualified Hydra.Json.Model as Model
import qualified Hydra.Overlay.Haskell.Lib.Equality as Equality
import qualified Hydra.Overlay.Haskell.Lib.Lists as Lists
import qualified Hydra.Overlay.Haskell.Lib.Literals as Literals
import qualified Hydra.Overlay.Haskell.Lib.Logic as Logic
import qualified Hydra.Overlay.Haskell.Lib.Optionals as Optionals
import qualified Hydra.Overlay.Haskell.Lib.Strings as Strings
import qualified Hydra.Packaging as Packaging
import qualified Hydra.Parsing as Parsing
import qualified Hydra.Paths as Paths
import qualified Hydra.Query as Query
import qualified Hydra.Relational as Relational
import qualified Hydra.Rust.Operators as Operators
import qualified Hydra.Rust.Syntax as Syntax
import qualified Hydra.Serialization as Serialization
import qualified Hydra.Tabular as Tabular
import qualified Hydra.Testing as Testing
import qualified Hydra.Topology as Topology
import qualified Hydra.Typed as Typed
import qualified Hydra.Typing as Typing
import qualified Hydra.Util as Util
import qualified Hydra.Validation as Validation
import qualified Hydra.Variants as Variants
import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
import qualified Data.Scientific as Sci
-- | Serialize an array expression
arrayExprToExpr :: Syntax.ArrayExpr -> Ast.Expr
arrayExprToExpr a =
    case a of
      Syntax.ArrayExprElements v0 -> Serialization.bracketList Serialization.halfBlockStyle (Lists.map expressionToExpr v0)
      Syntax.ArrayExprRepeat v0 ->
        let elem = Syntax.arrayRepeatElement v0
            len = Syntax.arrayRepeatLength v0
        in (Serialization.cst (Strings.cat [
          "[",
          (Serialization.printExpr (expressionToExpr elem)),
          "; ",
          (Serialization.printExpr (expressionToExpr len)),
          "]"]))
-- | Serialize an assignment expression
assignExprToExpr :: Syntax.AssignExpr -> Ast.Expr
assignExprToExpr a =

      let target = Syntax.assignExprTarget a
          val = Syntax.assignExprValue a
      in (Serialization.spaceSep [
        expressionToExpr target,
        (Serialization.cst "="),
        (expressionToExpr val)])
-- | Serialize an attribute
attributeToExpr :: Syntax.Attribute -> Ast.Expr
attributeToExpr attr =

      let inner = Syntax.attributeInner attr
          path = Syntax.attributePath attr
          tokens = Syntax.attributeTokens attr
          prefix = Logic.ifElse inner "#![" "#["
          pathStr = Strings.intercalate "::" path
          tokensPart =
                  Optionals.cases tokens "" (\t -> Strings.cat [
                    "(",
                    t,
                    ")"])
      in (Serialization.cst (Strings.cat [
        prefix,
        pathStr,
        tokensPart,
        "]"]))
-- | Serialize a binary expression
binaryExprToExpr :: Syntax.BinaryExpr -> Ast.Expr
binaryExprToExpr b =

      let left = Syntax.binaryExprLeft b
          op = Syntax.binaryExprOp b
          right = Syntax.binaryExprRight b
      in (Serialization.spaceSep [
        expressionToExpr left,
        (binaryOpToExpr op),
        (expressionToExpr right)])
-- | Serialize a binary operator
binaryOpToExpr :: Syntax.BinaryOp -> Ast.Expr
binaryOpToExpr op =
    Serialization.cst (case op of
      Syntax.BinaryOpAdd -> "+"
      Syntax.BinaryOpSub -> "-"
      Syntax.BinaryOpMul -> "*"
      Syntax.BinaryOpDiv -> "/"
      Syntax.BinaryOpRem -> "%"
      Syntax.BinaryOpAnd -> "&&"
      Syntax.BinaryOpOr -> "||"
      Syntax.BinaryOpBitAnd -> "&"
      Syntax.BinaryOpBitOr -> "|"
      Syntax.BinaryOpBitXor -> "^"
      Syntax.BinaryOpShl -> "<<"
      Syntax.BinaryOpShr -> ">>"
      Syntax.BinaryOpEq -> "=="
      Syntax.BinaryOpNe -> "!="
      Syntax.BinaryOpLt -> "<"
      Syntax.BinaryOpLe -> "<="
      Syntax.BinaryOpGt -> ">"
      Syntax.BinaryOpGe -> ">=")
-- | Serialize a block
blockToExpr :: Syntax.Block -> Ast.Expr
blockToExpr b =

      let stmts = Syntax.blockStatements b
          expr = Syntax.blockExpression b
          stmtExprs = Lists.map statementToExpr stmts
          exprPart = Optionals.cases expr [] (\e -> [
                expressionToExpr e])
          allParts = Lists.concat2 stmtExprs exprPart
      in (Serialization.curlyBracesList Nothing Serialization.halfBlockStyle allParts)
-- | Serialize a function call expression
callExprToExpr :: Syntax.CallExpr -> Ast.Expr
callExprToExpr c =

      let func = Syntax.callExprFunction c
          args = Syntax.callExprArgs c
      in (Serialization.spaceSep [
        expressionToExpr func,
        (Serialization.parenListAdaptive (Lists.map expressionToExpr args))])
-- | Serialize a cast expression
castExprToExpr :: Syntax.CastExpr -> Ast.Expr
castExprToExpr c =

      let expr = Syntax.castExprExpr c
          typ = Syntax.castExprType c
      in (Serialization.spaceSep [
        expressionToExpr expr,
        (Serialization.cst "as"),
        (typeToExpr typ)])
-- | Serialize a closure expression
closureExprToExpr :: Syntax.ClosureExpr -> Ast.Expr
closureExprToExpr c =

      let move = Syntax.closureExprMove c
          params = Syntax.closureExprParams c
          retType = Syntax.closureExprReturnType c
          body = Syntax.closureExprBody c
          moveKw = Logic.ifElse move (Just (Serialization.cst "move")) Nothing
          paramsStr =
                  Strings.cat [
                    "|",
                    (Strings.intercalate ", " (Lists.map closureParamToStr params)),
                    "|"]
          retPart =
                  Optionals.cases retType Nothing (\t -> Just (Serialization.spaceSep [
                    Serialization.cst "->",
                    (typeToExpr t)]))
      in (Serialization.spaceSep (Optionals.cat [
        moveKw,
        (Just (Serialization.cst paramsStr)),
        retPart,
        (Just (expressionToExpr body))]))
-- | Serialize a closure parameter to string
closureParamToStr :: Syntax.ClosureParam -> String
closureParamToStr cp =

      let pat = Syntax.closureParamPattern cp
          typ = Syntax.closureParamType cp
          patStr = Serialization.printExpr (patternToExpr pat)
      in (Optionals.cases typ patStr (\t -> Strings.cat [
        patStr,
        ": ",
        (Serialization.printExpr (typeToExpr t))]))
-- | Serialize a compound assignment expression
compoundAssignExprToExpr :: Syntax.CompoundAssignExpr -> Ast.Expr
compoundAssignExprToExpr c =

      let target = Syntax.compoundAssignExprTarget c
          op = Syntax.compoundAssignExprOp c
          val = Syntax.compoundAssignExprValue c
          opStr =
                  case op of
                    Syntax.CompoundAssignOpAddAssign -> "+="
                    Syntax.CompoundAssignOpSubAssign -> "-="
                    Syntax.CompoundAssignOpMulAssign -> "*="
                    Syntax.CompoundAssignOpDivAssign -> "/="
                    Syntax.CompoundAssignOpRemAssign -> "%="
                    Syntax.CompoundAssignOpBitAndAssign -> "&="
                    Syntax.CompoundAssignOpBitOrAssign -> "|="
                    Syntax.CompoundAssignOpBitXorAssign -> "^="
                    Syntax.CompoundAssignOpShlAssign -> "<<="
                    Syntax.CompoundAssignOpShrAssign -> ">>="
      in (Serialization.spaceSep [
        expressionToExpr target,
        (Serialization.cst opStr),
        (expressionToExpr val)])
-- | Serialize a const definition
constDefToExpr :: Syntax.ConstDef -> Ast.Expr
constDefToExpr c =

      let name = Syntax.constDefName c
          typ = Syntax.constDefType c
          val = Syntax.constDefValue c
      in (Serialization.spaceSep [
        Serialization.cst "const",
        (Serialization.cst (Strings.cat2 name ":")),
        (typeToExpr typ),
        (Serialization.cst "="),
        (expressionToExpr val),
        (Serialization.cst ";")])
-- | Serialize a Rust crate to an AST expression
crateToExpr :: Syntax.Crate -> Ast.Expr
crateToExpr crate = Serialization.doubleNewlineSep (Lists.map itemWithCommentsToExpr (Syntax.crateItems crate))
-- | Serialize derive macros to an attribute expression
derivesToExpr :: [String] -> Maybe Ast.Expr
derivesToExpr derives =
    Logic.ifElse (Lists.null derives) Nothing (Just (Serialization.cst (Strings.cat [
      "#[derive(",
      (Strings.intercalate ", " derives),
      ")]"])))
-- | Serialize an enum definition
enumDefToExpr :: Syntax.EnumDef -> Ast.Expr
enumDefToExpr e =

      let name = Syntax.enumDefName e
          generics = Syntax.enumDefGenerics e
          whereC = Syntax.enumDefWhereClause e
          variants = Syntax.enumDefVariants e
          derives = Syntax.enumDefDerives e
          docC = Syntax.enumDefDoc e
          derivesAttr = derivesToExpr derives
          docPart = Optionals.cases docC [] (\d -> [
                Serialization.cst (toRustDocComment d)])
          header =
                  Serialization.spaceSep (Optionals.cat [
                    Just (Serialization.cst "enum"),
                    (Just (Serialization.cst name)),
                    (genericParamsToExpr generics)])
          wherePart = Optionals.cases whereC Nothing (\w -> Just (whereClauseToExpr w))
          body = Serialization.curlyBracesList Nothing Serialization.halfBlockStyle (Lists.map enumVariantToExpr variants)
      in (Serialization.newlineSep (Lists.concat [
        docPart,
        (Optionals.cases derivesAttr [] (\d -> [
          d])),
        [
          Serialization.spaceSep (Optionals.cat [
            Just header,
            wherePart,
            (Just body)])]]))
-- | Serialize an enum variant body
enumVariantBodyToExpr :: Syntax.EnumVariantBody -> Ast.Expr
enumVariantBodyToExpr body =
    case body of
      Syntax.EnumVariantBodyUnit -> Serialization.cst ""
      Syntax.EnumVariantBodyTuple v0 -> Serialization.parenListAdaptive (Lists.map typeToExpr v0)
      Syntax.EnumVariantBodyStruct v0 -> Serialization.curlyBracesList Nothing Serialization.halfBlockStyle (Lists.map structFieldToExpr v0)
-- | Serialize an enum variant
enumVariantToExpr :: Syntax.EnumVariant -> Ast.Expr
enumVariantToExpr v =

      let name = Syntax.enumVariantName v
          body = Syntax.enumVariantBody v
          docC = Syntax.enumVariantDoc v
          docPart = Optionals.cases docC [] (\d -> [
                Serialization.cst (toRustDocComment d)])
      in (Serialization.newlineSep (Lists.concat [
        docPart,
        [
          Serialization.spaceSep [
            Serialization.cst name,
            (enumVariantBodyToExpr body)]]]))
-- | Serialize an expression path
exprPathToExpr :: Syntax.ExprPath -> Ast.Expr
exprPathToExpr ep =

      let global = Syntax.exprPathGlobal ep
          segs = Syntax.exprPathSegments ep
          prefix = Logic.ifElse global "::" ""
          segStrs = Lists.map (\s -> Serialization.printExpr (pathSegmentToExpr s)) segs
      in (Serialization.cst (Strings.cat2 prefix (Strings.intercalate "::" segStrs)))
-- | Serialize a Rust expression
expressionToExpr :: Syntax.Expression -> Ast.Expr
expressionToExpr expr =
    case expr of
      Syntax.ExpressionLiteral v0 -> literalToExpr v0
      Syntax.ExpressionPath v0 -> exprPathToExpr v0
      Syntax.ExpressionBlock v0 -> blockToExpr v0
      Syntax.ExpressionCall v0 -> callExprToExpr v0
      Syntax.ExpressionMethodCall v0 -> methodCallExprToExpr v0
      Syntax.ExpressionFieldAccess v0 -> fieldAccessExprToExpr v0
      Syntax.ExpressionTupleIndex v0 -> tupleIndexExprToExpr v0
      Syntax.ExpressionClosure v0 -> closureExprToExpr v0
      Syntax.ExpressionIf v0 -> ifExprToExpr v0
      Syntax.ExpressionMatch v0 -> matchExprToExpr v0
      Syntax.ExpressionLoop v0 -> loopExprToExpr v0
      Syntax.ExpressionWhile v0 -> whileExprToExpr v0
      Syntax.ExpressionFor v0 -> forExprToExpr v0
      Syntax.ExpressionBinary v0 -> binaryExprToExpr v0
      Syntax.ExpressionUnary v0 -> unaryExprToExpr v0
      Syntax.ExpressionReference v0 -> refExprToExpr v0
      Syntax.ExpressionDereference v0 -> Serialization.prefix "*" (expressionToExpr v0)
      Syntax.ExpressionStruct v0 -> structExprToExpr v0
      Syntax.ExpressionTuple v0 -> Serialization.parenListAdaptive (Lists.map expressionToExpr v0)
      Syntax.ExpressionArray v0 -> arrayExprToExpr v0
      Syntax.ExpressionIndex v0 -> indexExprToExpr v0
      Syntax.ExpressionRange v0 -> rangeExprToExpr v0
      Syntax.ExpressionReturn v0 -> Optionals.cases v0 (Serialization.cst "return") (\e -> Serialization.spaceSep [
        Serialization.cst "return",
        (expressionToExpr e)])
      Syntax.ExpressionBreak v0 -> Optionals.cases v0 (Serialization.cst "break") (\e -> Serialization.spaceSep [
        Serialization.cst "break",
        (expressionToExpr e)])
      Syntax.ExpressionContinue -> Serialization.cst "continue"
      Syntax.ExpressionTry v0 -> Serialization.cst (Strings.cat2 (Serialization.printExpr (expressionToExpr v0)) "?")
      Syntax.ExpressionCast v0 -> castExprToExpr v0
      Syntax.ExpressionTypeAscription v0 -> typeAscriptionExprToExpr v0
      Syntax.ExpressionAwait v0 -> Serialization.cst (Strings.cat2 (Serialization.printExpr (expressionToExpr v0)) ".await")
      Syntax.ExpressionAssign v0 -> assignExprToExpr v0
      Syntax.ExpressionCompoundAssign v0 -> compoundAssignExprToExpr v0
      Syntax.ExpressionMacro v0 -> macroInvocationToExpr v0
      Syntax.ExpressionParen v0 -> Serialization.parenthesize (expressionToExpr v0)
-- | Serialize a field access expression
fieldAccessExprToExpr :: Syntax.FieldAccessExpr -> Ast.Expr
fieldAccessExprToExpr f =

      let obj = Syntax.fieldAccessExprObject f
          field = Syntax.fieldAccessExprField f
      in (Serialization.cst (Strings.cat [
        Serialization.printExpr (expressionToExpr obj),
        ".",
        field]))
-- | Serialize a field pattern
fieldPatternToExpr :: Syntax.FieldPattern -> Ast.Expr
fieldPatternToExpr fp =

      let name = Syntax.fieldPatternName fp
          pat = Syntax.fieldPatternPattern fp
      in (Optionals.cases pat (Serialization.cst name) (\p -> Serialization.spaceSep [
        Serialization.cst (Strings.cat2 name ":"),
        (patternToExpr p)]))
-- | Serialize a field-value pair
fieldValueToExpr :: Syntax.FieldValue -> Ast.Expr
fieldValueToExpr fv =

      let name = Syntax.fieldValueName fv
          val = Syntax.fieldValueValue fv
      in (Optionals.cases val (Serialization.cst name) (\v -> Serialization.spaceSep [
        Serialization.cst (Strings.cat2 name ":"),
        (expressionToExpr v)]))
-- | Serialize a float literal
floatLiteralToExpr :: Syntax.FloatLiteral -> Ast.Expr
floatLiteralToExpr fl =

      let val = Syntax.floatLiteralValue fl
          suf = Syntax.floatLiteralSuffix fl
          valStr = Literals.showFloat64 val
          sufStr = Optionals.cases suf "" (\s -> s)
      in (Serialization.cst (Strings.cat2 valStr sufStr))
-- | Serialize a function definition
fnDefToExpr :: Syntax.FnDef -> Ast.Expr
fnDefToExpr f =

      let name = Syntax.fnDefName f
          generics = Syntax.fnDefGenerics f
          whereC = Syntax.fnDefWhereClause f
          params = Syntax.fnDefParams f
          retType = Syntax.fnDefReturnType f
          body = Syntax.fnDefBody f
          isAsync = Syntax.fnDefAsync f
          isConst = Syntax.fnDefConst f
          isUnsafe = Syntax.fnDefUnsafe f
          docC = Syntax.fnDefDoc f
          docPart = Optionals.cases docC [] (\d -> [
                Serialization.cst (toRustDocComment d)])
          asyncKw = Logic.ifElse isAsync (Just (Serialization.cst "async")) Nothing
          constKw = Logic.ifElse isConst (Just (Serialization.cst "const")) Nothing
          unsafeKw = Logic.ifElse isUnsafe (Just (Serialization.cst "unsafe")) Nothing
          fnKw = Serialization.cst "fn"
          nameExpr = Serialization.cst name
          genericsExpr = genericParamsToExpr generics
          paramsExpr = Serialization.parenListAdaptive (Lists.map fnParamToExpr params)
          retTypeExpr =
                  Optionals.cases retType Nothing (\t -> Just (Serialization.spaceSep [
                    Serialization.cst "->",
                    (typeToExpr t)]))
          whereExpr = Optionals.cases whereC Nothing (\w -> Just (whereClauseToExpr w))
          header =
                  Serialization.spaceSep (Optionals.cat [
                    asyncKw,
                    constKw,
                    unsafeKw,
                    (Just fnKw),
                    (Just nameExpr),
                    genericsExpr,
                    (Just paramsExpr),
                    retTypeExpr,
                    whereExpr])
      in (Serialization.newlineSep (Lists.concat [
        docPart,
        [
          Serialization.spaceSep [
            header,
            (blockToExpr body)]]]))
-- | Serialize a function parameter
fnParamToExpr :: Syntax.FnParam -> Ast.Expr
fnParamToExpr param =

      let pat = Syntax.fnParamPattern param
          typ = Syntax.fnParamType param
      in (Serialization.spaceSep [
        Serialization.cst (Strings.cat2 (Serialization.printExpr (patternToExpr pat)) ":"),
        (typeToExpr typ)])
-- | Serialize a for expression
forExprToExpr :: Syntax.ForExpr -> Ast.Expr
forExprToExpr f =

      let label = Syntax.forExprLabel f
          pat = Syntax.forExprPattern f
          iter = Syntax.forExprIter f
          body = Syntax.forExprBody f
          labelPart = Optionals.cases label Nothing (\lbl -> Just (Serialization.cst (Strings.cat2 "'" (Strings.cat2 lbl ":"))))
      in (Serialization.spaceSep (Optionals.cat [
        labelPart,
        (Just (Serialization.cst "for")),
        (Just (patternToExpr pat)),
        (Just (Serialization.cst "in")),
        (Just (expressionToExpr iter)),
        (Just (blockToExpr body))]))
-- | Serialize a generic argument
genericArgToExpr :: Syntax.GenericArg -> Ast.Expr
genericArgToExpr arg =
    case arg of
      Syntax.GenericArgType v0 -> typeToExpr v0
      Syntax.GenericArgLifetime v0 -> Serialization.cst (Strings.cat2 "'" (Syntax.lifetimeName v0))
      Syntax.GenericArgConst v0 -> expressionToExpr v0
      Syntax.GenericArgBinding v0 ->
        let name = Syntax.typeBindingName v0
            typ = Syntax.typeBindingType v0
        in (Serialization.spaceSep [
          Serialization.cst name,
          (Serialization.cst "="),
          (typeToExpr typ)])
-- | Serialize generic arguments
genericArgumentsToExpr :: Syntax.GenericArguments -> Maybe Ast.Expr
genericArgumentsToExpr args =
    case args of
      Syntax.GenericArgumentsNone -> Nothing
      Syntax.GenericArgumentsAngleBracketed v0 ->
        let args = Syntax.angleBracketedArgsArgs v0
        in (Just (Serialization.angleBracesList Serialization.inlineStyle (Lists.map genericArgToExpr args)))
      Syntax.GenericArgumentsParenthesized v0 ->
        let inputs = Syntax.parenthesizedArgsInputs v0
            output = Syntax.parenthesizedArgsOutput v0
            inputPart = Serialization.parenListAdaptive (Lists.map typeToExpr inputs)
            outputPart =
                    Optionals.cases output Nothing (\t -> Just (Serialization.spaceSep [
                      Serialization.cst "->",
                      (typeToExpr t)]))
        in (Just (Serialization.spaceSep (Optionals.cat [
          Just inputPart,
          outputPart])))
-- | Serialize a generic parameter
genericParamToExpr :: Syntax.GenericParam -> Ast.Expr
genericParamToExpr gp =

      let name = Syntax.genericParamName gp
          bounds = Syntax.genericParamBounds gp
      in (Logic.ifElse (Lists.null bounds) (Serialization.cst name) (Serialization.spaceSep [
        Serialization.cst (Strings.cat2 name ":"),
        (Serialization.cst (Strings.intercalate " + " (Lists.map (\b -> Serialization.printExpr (typeParamBoundToExpr b)) bounds)))]))
-- | Serialize a list of generic parameters
genericParamsToExpr :: [Syntax.GenericParam] -> Maybe Ast.Expr
genericParamsToExpr gps =
    Logic.ifElse (Lists.null gps) Nothing (Just (Serialization.angleBracesList Serialization.inlineStyle (Lists.map genericParamToExpr gps)))
-- | Serialize an identifier pattern
identifierPatternToExpr :: Syntax.IdentifierPattern -> Ast.Expr
identifierPatternToExpr ip =

      let name = Syntax.identifierPatternName ip
          mut = Syntax.identifierPatternMutable ip
          atPat = Syntax.identifierPatternAtPattern ip
          mutKw = Logic.ifElse mut (Just (Serialization.cst "mut")) Nothing
          atPart =
                  Optionals.cases atPat Nothing (\p -> Just (Serialization.spaceSep [
                    Serialization.cst "@",
                    (patternToExpr p)]))
      in (Serialization.spaceSep (Optionals.cat [
        mutKw,
        (Just (Serialization.cst name)),
        atPart]))
-- | Serialize an if expression
ifExprToExpr :: Syntax.IfExpr -> Ast.Expr
ifExprToExpr i =

      let cond = Syntax.ifExprCondition i
          thenB = Syntax.ifExprThenBlock i
          elseB = Syntax.ifExprElseBranch i
          condExpr =
                  case cond of
                    Syntax.IfConditionBool v0 -> expressionToExpr v0
                    Syntax.IfConditionLet v0 ->
                      let pat = Syntax.letConditionPattern v0
                          expr = Syntax.letConditionExpr v0
                      in (Serialization.spaceSep [
                        Serialization.cst "let",
                        (patternToExpr pat),
                        (Serialization.cst "="),
                        (expressionToExpr expr)])
          elsePart =
                  Optionals.cases elseB Nothing (\e -> Just (Serialization.spaceSep [
                    Serialization.cst "else",
                    (expressionToExpr e)]))
      in (Serialization.spaceSep (Optionals.cat [
        Just (Serialization.cst "if"),
        (Just condExpr),
        (Just (blockToExpr thenB)),
        elsePart]))
-- | Serialize an impl block
implBlockToExpr :: Syntax.ImplBlock -> Ast.Expr
implBlockToExpr i =

      let generics = Syntax.implBlockGenerics i
          whereC = Syntax.implBlockWhereClause i
          trait = Syntax.implBlockTrait i
          selfType = Syntax.implBlockSelfType i
          items = Syntax.implBlockItems i
          genericsExpr = genericParamsToExpr generics
          traitPart =
                  Optionals.cases trait Nothing (\t -> Just (Serialization.spaceSep [
                    typePathToExpr t,
                    (Serialization.cst "for")]))
          wherePart = Optionals.cases whereC Nothing (\w -> Just (whereClauseToExpr w))
          header =
                  Serialization.spaceSep (Optionals.cat [
                    Just (Serialization.cst "impl"),
                    genericsExpr,
                    traitPart,
                    (Just (typeToExpr selfType)),
                    wherePart])
          body = Serialization.curlyBracesList Nothing Serialization.halfBlockStyle (Lists.map implItemToExpr items)
      in (Serialization.spaceSep [
        header,
        body])
-- | Serialize an impl item
implItemToExpr :: Syntax.ImplItem -> Ast.Expr
implItemToExpr item =
    case item of
      Syntax.ImplItemMethod v0 -> implMethodToExpr v0
      Syntax.ImplItemType v0 -> typeAliasToExpr v0
      Syntax.ImplItemConst v0 -> constDefToExpr v0
-- | Serialize an impl method
implMethodToExpr :: Syntax.ImplMethod -> Ast.Expr
implMethodToExpr m =

      let name = Syntax.implMethodName m
          generics = Syntax.implMethodGenerics m
          whereC = Syntax.implMethodWhereClause m
          params = Syntax.implMethodParams m
          retType = Syntax.implMethodReturnType m
          body = Syntax.implMethodBody m
          pub = Syntax.implMethodPublic m
          docC = Syntax.implMethodDoc m
          docPart = Optionals.cases docC [] (\d -> [
                Serialization.cst (toRustDocComment d)])
          pubKw = Logic.ifElse pub (Just (Serialization.cst "pub")) Nothing
          genericsExpr = genericParamsToExpr generics
          paramsExpr = Serialization.parenListAdaptive (Lists.map methodParamToExpr params)
          retTypeExpr =
                  Optionals.cases retType Nothing (\t -> Just (Serialization.spaceSep [
                    Serialization.cst "->",
                    (typeToExpr t)]))
          whereExpr = Optionals.cases whereC Nothing (\w -> Just (whereClauseToExpr w))
          header =
                  Serialization.spaceSep (Optionals.cat [
                    pubKw,
                    (Just (Serialization.cst "fn")),
                    (Just (Serialization.cst name)),
                    genericsExpr,
                    (Just paramsExpr),
                    retTypeExpr,
                    whereExpr])
      in (Serialization.newlineSep (Lists.concat [
        docPart,
        [
          Serialization.spaceSep [
            header,
            (blockToExpr body)]]]))
-- | Serialize an index expression
indexExprToExpr :: Syntax.IndexExpr -> Ast.Expr
indexExprToExpr i =

      let obj = Syntax.indexExprObject i
          idx = Syntax.indexExprIndex i
      in (Serialization.cst (Strings.cat [
        Serialization.printExpr (expressionToExpr obj),
        "[",
        (Serialization.printExpr (expressionToExpr idx)),
        "]"]))
-- | Serialize an integer literal
integerLiteralToExpr :: Syntax.IntegerLiteral -> Ast.Expr
integerLiteralToExpr il =

      let val = Syntax.integerLiteralValue il
          suf = Syntax.integerLiteralSuffix il
          valStr = Literals.showBigint val
          sufStr = Optionals.cases suf "" (\s -> s)
      in (Serialization.cst (Strings.cat2 valStr sufStr))
-- | Serialize a Rust item to an AST expression
itemToExpr :: Syntax.Item -> Ast.Expr
itemToExpr item =
    case item of
      Syntax.ItemUse v0 -> useDeclarationToExpr v0
      Syntax.ItemStruct v0 -> structDefToExpr v0
      Syntax.ItemEnum v0 -> enumDefToExpr v0
      Syntax.ItemFn v0 -> fnDefToExpr v0
      Syntax.ItemTypeAlias v0 -> typeAliasToExpr v0
      Syntax.ItemImpl v0 -> implBlockToExpr v0
      Syntax.ItemTrait v0 -> traitDefToExpr v0
      Syntax.ItemMod v0 -> modDefToExpr v0
      Syntax.ItemConst v0 -> constDefToExpr v0
      Syntax.ItemStatic v0 -> staticDefToExpr v0
      Syntax.ItemMacro v0 -> macroInvocationToExpr v0
-- | Serialize an item with optional doc comments and visibility
itemWithCommentsToExpr :: Syntax.ItemWithComments -> Ast.Expr
itemWithCommentsToExpr iwc =

      let doc = Syntax.itemWithCommentsDoc iwc
          vis = Syntax.itemWithCommentsVisibility iwc
          item = Syntax.itemWithCommentsItem iwc
          docPart = Optionals.cases doc [] (\d -> [
                Serialization.cst (toRustDocComment d)])
          visPart = visibilityToExpr vis
          itemPart = itemToExpr item
      in (Serialization.newlineSep (Lists.concat [
        docPart,
        [
          Serialization.spaceSep (Optionals.cat [
            visPart,
            (Just itemPart)])]]))
-- | Serialize a let statement
letStatementToExpr :: Syntax.LetStatement -> Ast.Expr
letStatementToExpr l =

      let pat = Syntax.letStatementPattern l
          mut = Syntax.letStatementMutable l
          typ = Syntax.letStatementType l
          init = Syntax.letStatementInit l
          mutKw = Logic.ifElse mut (Just (Serialization.cst "mut")) Nothing
          typPart =
                  Optionals.cases typ Nothing (\t -> Just (Serialization.spaceSep [
                    Serialization.cst ":",
                    (typeToExpr t)]))
          initPart =
                  Optionals.cases init Nothing (\e -> Just (Serialization.spaceSep [
                    Serialization.cst "=",
                    (expressionToExpr e)]))
      in (Serialization.spaceSep (Optionals.cat [
        Just (Serialization.cst "let"),
        mutKw,
        (Just (patternToExpr pat)),
        typPart,
        initPart,
        (Just (Serialization.cst ";"))]))
-- | Serialize a literal
literalToExpr :: Syntax.Literal -> Ast.Expr
literalToExpr lit =
    case lit of
      Syntax.LiteralInteger v0 -> integerLiteralToExpr v0
      Syntax.LiteralFloat v0 -> floatLiteralToExpr v0
      Syntax.LiteralString v0 -> Serialization.cst (Literals.showString v0)
      Syntax.LiteralRawString v0 -> Serialization.cst (Strings.cat [
        "r\"",
        v0,
        "\""])
      Syntax.LiteralByteString _ -> Serialization.cst "b\"...\""
      Syntax.LiteralChar v0 -> Serialization.cst (Strings.cat [
        "'",
        (Literals.showUint32 v0),
        "'"])
      Syntax.LiteralByte v0 -> Serialization.cst (Strings.cat [
        "b'",
        (Literals.showUint8 v0),
        "'"])
      Syntax.LiteralBool v0 -> Serialization.cst (Logic.ifElse v0 "true" "false")
-- | Serialize a loop expression
loopExprToExpr :: Syntax.LoopExpr -> Ast.Expr
loopExprToExpr l =

      let label = Syntax.loopExprLabel l
          body = Syntax.loopExprBody l
          labelPart = Optionals.cases label Nothing (\lbl -> Just (Serialization.cst (Strings.cat2 "'" (Strings.cat2 lbl ":"))))
      in (Serialization.spaceSep (Optionals.cat [
        labelPart,
        (Just (Serialization.cst "loop")),
        (Just (blockToExpr body))]))
-- | Serialize a macro invocation
macroInvocationToExpr :: Syntax.MacroInvocation -> Ast.Expr
macroInvocationToExpr m =

      let path = Syntax.macroInvocationPath m
          delim = Syntax.macroInvocationDelimiter m
          tokens = Syntax.macroInvocationTokens m
          pathStr = Strings.intercalate "::" path
          open =
                  case delim of
                    Syntax.MacroDelimiterParen -> "("
                    Syntax.MacroDelimiterBracket -> "["
                    Syntax.MacroDelimiterBrace -> "{"
          close =
                  case delim of
                    Syntax.MacroDelimiterParen -> ")"
                    Syntax.MacroDelimiterBracket -> "]"
                    Syntax.MacroDelimiterBrace -> "}"
      in (Serialization.cst (Strings.cat [
        pathStr,
        "!",
        open,
        tokens,
        close]))
-- | Serialize a match arm
matchArmToExpr :: Syntax.MatchArm -> Ast.Expr
matchArmToExpr arm =

      let pat = Syntax.matchArmPattern arm
          guard = Syntax.matchArmGuard arm
          body = Syntax.matchArmBody arm
          guardPart =
                  Optionals.cases guard Nothing (\g -> Just (Serialization.spaceSep [
                    Serialization.cst "if",
                    (expressionToExpr g)]))
      in (Serialization.spaceSep (Optionals.cat [
        Just (patternToExpr pat),
        guardPart,
        (Just (Serialization.cst "=>")),
        (Just (expressionToExpr body)),
        (Just (Serialization.cst ","))]))
-- | Serialize a match expression
matchExprToExpr :: Syntax.MatchExpr -> Ast.Expr
matchExprToExpr m =

      let scrut = Syntax.matchExprScrutinee m
          arms = Syntax.matchExprArms m
      in (Serialization.spaceSep [
        Serialization.cst "match",
        (expressionToExpr scrut),
        (Serialization.curlyBracesList Nothing Serialization.halfBlockStyle (Lists.map matchArmToExpr arms))])
-- | Serialize a method call expression
methodCallExprToExpr :: Syntax.MethodCallExpr -> Ast.Expr
methodCallExprToExpr m =

      let recv = Syntax.methodCallExprReceiver m
          method = Syntax.methodCallExprMethod m
          turbo = Syntax.methodCallExprTurbofish m
          args = Syntax.methodCallExprArgs m
          turboPart =
                  Logic.ifElse (Lists.null turbo) "" (Strings.cat [
                    "::<",
                    (Strings.intercalate ", " (Lists.map (\t -> Serialization.printExpr (typeToExpr t)) turbo)),
                    ">"])
      in (Serialization.cst (Strings.cat [
        Serialization.printExpr (expressionToExpr recv),
        ".",
        method,
        turboPart,
        "(",
        (Strings.intercalate ", " (Lists.map (\a -> Serialization.printExpr (expressionToExpr a)) args)),
        ")"]))
-- | Serialize a method parameter
methodParamToExpr :: Syntax.MethodParam -> Ast.Expr
methodParamToExpr param =
    case param of
      Syntax.MethodParamSelf v0 -> case v0 of
        Syntax.SelfParamOwned -> Serialization.cst "self"
        Syntax.SelfParamRef -> Serialization.cst "&self"
        Syntax.SelfParamRefMut -> Serialization.cst "&mut self"
      Syntax.MethodParamRegular v0 -> fnParamToExpr v0
-- | Serialize a module definition
modDefToExpr :: Syntax.ModDef -> Ast.Expr
modDefToExpr m =

      let name = Syntax.modDefName m
          body = Syntax.modDefBody m
      in (Optionals.cases body (Serialization.spaceSep [
        Serialization.cst "mod",
        (Serialization.cst name),
        (Serialization.cst ";")]) (\items -> Serialization.spaceSep [
        Serialization.cst "mod",
        (Serialization.cst name),
        (Serialization.curlyBracesList Nothing Serialization.halfBlockStyle (Lists.map itemToExpr items))]))
-- | Serialize a path segment
pathSegmentToExpr :: Syntax.PathSegment -> Ast.Expr
pathSegmentToExpr seg =

      let name = Syntax.pathSegmentName seg
          args = Syntax.pathSegmentArguments seg
      in (Serialization.spaceSep (Optionals.cat [
        Just (Serialization.cst name),
        (genericArgumentsToExpr args)]))
-- | Serialize a pattern
patternToExpr :: Syntax.Pattern -> Ast.Expr
patternToExpr pat =
    case pat of
      Syntax.PatternWildcard -> Serialization.cst "_"
      Syntax.PatternIdentifier v0 -> identifierPatternToExpr v0
      Syntax.PatternLiteral v0 -> literalToExpr v0
      Syntax.PatternReference v0 -> refPatternToExpr v0
      Syntax.PatternStruct v0 -> structPatternToExpr v0
      Syntax.PatternTupleStruct v0 -> tupleStructPatternToExpr v0
      Syntax.PatternTuple v0 -> Serialization.parenListAdaptive (Lists.map patternToExpr v0)
      Syntax.PatternSlice v0 -> Serialization.bracketList Serialization.halfBlockStyle (Lists.map patternToExpr v0)
      Syntax.PatternOr v0 -> Serialization.cst (Strings.intercalate " | " (Lists.map (\p -> Serialization.printExpr (patternToExpr p)) v0))
      Syntax.PatternPath v0 -> exprPathToExpr v0
      Syntax.PatternRange v0 -> rangePatternToExpr v0
      Syntax.PatternRest -> Serialization.cst ".."
      Syntax.PatternParen v0 -> Serialization.parenthesize (patternToExpr v0)
-- | Serialize a range expression
rangeExprToExpr :: Syntax.RangeExpr -> Ast.Expr
rangeExprToExpr r =

      let from = Syntax.rangeExprFrom r
          to = Syntax.rangeExprTo r
          incl = Syntax.rangeExprInclusive r
          fromStr = Optionals.cases from "" (\f -> Serialization.printExpr (expressionToExpr f))
          toStr = Optionals.cases to "" (\t -> Serialization.printExpr (expressionToExpr t))
          op = Logic.ifElse incl "..=" ".."
      in (Serialization.cst (Strings.cat [
        fromStr,
        op,
        toStr]))
-- | Serialize a range pattern
rangePatternToExpr :: Syntax.RangePattern -> Ast.Expr
rangePatternToExpr rp =

      let from = Syntax.rangePatternFrom rp
          to = Syntax.rangePatternTo rp
          incl = Syntax.rangePatternInclusive rp
          fromStr = Optionals.cases from "" (\p -> Serialization.printExpr (patternToExpr p))
          toStr = Optionals.cases to "" (\p -> Serialization.printExpr (patternToExpr p))
          op = Logic.ifElse incl "..=" ".."
      in (Serialization.cst (Strings.cat [
        fromStr,
        op,
        toStr]))
-- | Serialize a reference expression
refExprToExpr :: Syntax.RefExpr -> Ast.Expr
refExprToExpr r =

      let mut = Syntax.refExprMutable r
          expr = Syntax.refExprExpr r
          prefix = Logic.ifElse mut "&mut " "&"
      in (Serialization.cst (Strings.cat2 prefix (Serialization.printExpr (expressionToExpr expr))))
-- | Serialize a reference pattern
refPatternToExpr :: Syntax.RefPattern -> Ast.Expr
refPatternToExpr rp =

      let mut = Syntax.refPatternMutable rp
          pat = Syntax.refPatternPattern rp
          prefix = Logic.ifElse mut "&mut " "&"
      in (Serialization.cst (Strings.cat2 prefix (Serialization.printExpr (patternToExpr pat))))
-- | Serialize a reference type
referenceTypeToExpr :: Syntax.ReferenceType -> Ast.Expr
referenceTypeToExpr rt =

      let lt = Syntax.referenceTypeLifetime rt
          mut = Syntax.referenceTypeMutable rt
          t = Syntax.referenceTypeType rt
          ltPart = Optionals.cases lt "" (\l -> Strings.cat2 "'" (Strings.cat2 (Syntax.lifetimeName l) " "))
          mutPart = Logic.ifElse mut "mut " ""
      in (Serialization.cst (Strings.cat [
        "&",
        ltPart,
        mutPart,
        (Serialization.printExpr (typeToExpr t))]))
-- | Serialize a statement
statementToExpr :: Syntax.Statement -> Ast.Expr
statementToExpr stmt =
    case stmt of
      Syntax.StatementLet v0 -> letStatementToExpr v0
      Syntax.StatementExpression v0 -> Serialization.spaceSep [
        expressionToExpr v0,
        (Serialization.cst ";")]
      Syntax.StatementItem v0 -> itemToExpr v0
      Syntax.StatementEmpty -> Serialization.cst ";"
-- | Serialize a static definition
staticDefToExpr :: Syntax.StaticDef -> Ast.Expr
staticDefToExpr s =

      let name = Syntax.staticDefName s
          typ = Syntax.staticDefType s
          val = Syntax.staticDefValue s
          mut = Syntax.staticDefMutable s
          mutKw = Logic.ifElse mut (Just (Serialization.cst "mut")) Nothing
      in (Serialization.spaceSep (Optionals.cat [
        Just (Serialization.cst "static"),
        mutKw,
        (Just (Serialization.cst (Strings.cat2 name ":"))),
        (Just (typeToExpr typ)),
        (Just (Serialization.cst "=")),
        (Just (expressionToExpr val)),
        (Just (Serialization.cst ";"))]))
-- | Serialize a struct body
structBodyToExpr :: Syntax.StructBody -> Ast.Expr
structBodyToExpr body =
    case body of
      Syntax.StructBodyNamed v0 -> Serialization.curlyBracesList Nothing Serialization.halfBlockStyle (Lists.map structFieldToExpr v0)
      Syntax.StructBodyTuple v0 -> Serialization.spaceSep [
        Serialization.parenListAdaptive (Lists.map (\f -> typeToExpr (Syntax.tupleFieldType f)) v0),
        (Serialization.cst ";")]
      Syntax.StructBodyUnit -> Serialization.cst ";"
-- | Serialize a struct definition
structDefToExpr :: Syntax.StructDef -> Ast.Expr
structDefToExpr s =

      let name = Syntax.structDefName s
          generics = Syntax.structDefGenerics s
          whereC = Syntax.structDefWhereClause s
          body = Syntax.structDefBody s
          derives = Syntax.structDefDerives s
          docC = Syntax.structDefDoc s
          derivesAttr = derivesToExpr derives
          docPart = Optionals.cases docC [] (\d -> [
                Serialization.cst (toRustDocComment d)])
          header =
                  Serialization.spaceSep (Optionals.cat [
                    Just (Serialization.cst "struct"),
                    (Just (Serialization.cst name)),
                    (genericParamsToExpr generics)])
          wherePart = Optionals.cases whereC Nothing (\w -> Just (whereClauseToExpr w))
      in (Serialization.newlineSep (Lists.concat [
        docPart,
        (Optionals.cases derivesAttr [] (\d -> [
          d])),
        [
          Serialization.spaceSep (Optionals.cat [
            Just header,
            wherePart,
            (Just (structBodyToExpr body))])]]))
-- | Serialize a struct literal expression
structExprToExpr :: Syntax.StructExpr -> Ast.Expr
structExprToExpr s =

      let path = Syntax.structExprPath s
          fields = Syntax.structExprFields s
          rest = Syntax.structExprRest s
          fieldExprs = Lists.map fieldValueToExpr fields
          restExpr =
                  Optionals.cases rest [] (\r -> [
                    Serialization.spaceSep [
                      Serialization.cst "..",
                      (expressionToExpr r)]])
          allFields = Lists.concat2 fieldExprs restExpr
      in (Serialization.spaceSep [
        exprPathToExpr path,
        (Serialization.curlyBracesList Nothing Serialization.halfBlockStyle allFields)])
-- | Serialize a struct field
structFieldToExpr :: Syntax.StructField -> Ast.Expr
structFieldToExpr field =

      let name = Syntax.structFieldName field
          typ = Syntax.structFieldType field
          pub = Syntax.structFieldPublic field
          docC = Syntax.structFieldDoc field
          pubKw = Logic.ifElse pub (Just (Serialization.cst "pub")) Nothing
          docPart = Optionals.cases docC [] (\d -> [
                Serialization.cst (toRustDocComment d)])
      in (Serialization.newlineSep (Lists.concat [
        docPart,
        [
          Serialization.spaceSep (Optionals.cat [
            pubKw,
            (Just (Serialization.cst (Strings.cat2 name ":"))),
            (Just (typeToExpr typ))])]]))
-- | Serialize a struct pattern
structPatternToExpr :: Syntax.StructPattern -> Ast.Expr
structPatternToExpr sp =

      let path = Syntax.structPatternPath sp
          fields = Syntax.structPatternFields sp
          rest = Syntax.structPatternRest sp
          fieldExprs = Lists.map fieldPatternToExpr fields
          restExpr = Logic.ifElse rest [
                Serialization.cst ".."] []
          allFields = Lists.concat2 fieldExprs restExpr
      in (Serialization.spaceSep [
        exprPathToExpr path,
        (Serialization.curlyBracesList Nothing Serialization.halfBlockStyle allFields)])
-- | Convert a string to Rust line comments. Empty source lines emit `//` (no trailing space).
toRustComment :: String -> String
toRustComment c =
    Strings.intercalate "\n" (Lists.map (\s -> Logic.ifElse (Equality.equal s "") "//" (Strings.cat2 "// " s)) (Strings.lines c))
-- | Convert a string to Rust doc comments. Empty source lines emit `///` (no trailing space) so blank doc lines don't carry trailing whitespace.
toRustDocComment :: String -> String
toRustDocComment c =
    Strings.intercalate "\n" (Lists.map (\s -> Logic.ifElse (Equality.equal s "") "///" (Strings.cat2 "/// " s)) (Strings.lines c))
-- | Serialize a trait associated constant
traitConstToExpr :: Syntax.TraitConst -> Ast.Expr
traitConstToExpr c =

      let name = Syntax.traitConstName c
          typ = Syntax.traitConstType c
          def = Syntax.traitConstDefault c
          defPart =
                  Optionals.cases def Nothing (\d -> Just (Serialization.spaceSep [
                    Serialization.cst "=",
                    (expressionToExpr d)]))
      in (Serialization.spaceSep (Optionals.cat [
        Just (Serialization.cst "const"),
        (Just (Serialization.cst (Strings.cat2 name ":"))),
        (Just (typeToExpr typ)),
        defPart,
        (Just (Serialization.cst ";"))]))
-- | Serialize a trait definition
traitDefToExpr :: Syntax.TraitDef -> Ast.Expr
traitDefToExpr t =

      let name = Syntax.traitDefName t
          generics = Syntax.traitDefGenerics t
          whereC = Syntax.traitDefWhereClause t
          supers = Syntax.traitDefSuperTraits t
          items = Syntax.traitDefItems t
          isUnsafe = Syntax.traitDefUnsafe t
          docC = Syntax.traitDefDoc t
          docPart = Optionals.cases docC [] (\d -> [
                Serialization.cst (toRustDocComment d)])
          unsafeKw = Logic.ifElse isUnsafe (Just (Serialization.cst "unsafe")) Nothing
          genericsExpr = genericParamsToExpr generics
          superPart =
                  Logic.ifElse (Lists.null supers) Nothing (Just (Serialization.spaceSep [
                    Serialization.cst ":",
                    (Serialization.cst (Strings.intercalate " + " (Lists.map (\b -> Serialization.printExpr (typeParamBoundToExpr b)) supers)))]))
          wherePart = Optionals.cases whereC Nothing (\w -> Just (whereClauseToExpr w))
          header =
                  Serialization.spaceSep (Optionals.cat [
                    unsafeKw,
                    (Just (Serialization.cst "trait")),
                    (Just (Serialization.cst name)),
                    genericsExpr,
                    superPart,
                    wherePart])
          body = Serialization.curlyBracesList Nothing Serialization.halfBlockStyle (Lists.map traitItemToExpr items)
      in (Serialization.newlineSep (Lists.concat [
        docPart,
        [
          Serialization.spaceSep [
            header,
            body]]]))
-- | Serialize a trait item
traitItemToExpr :: Syntax.TraitItem -> Ast.Expr
traitItemToExpr item =
    case item of
      Syntax.TraitItemMethod v0 -> traitMethodToExpr v0
      Syntax.TraitItemType v0 -> traitTypeToExpr v0
      Syntax.TraitItemConst v0 -> traitConstToExpr v0
-- | Serialize a trait method
traitMethodToExpr :: Syntax.TraitMethod -> Ast.Expr
traitMethodToExpr m =

      let name = Syntax.traitMethodName m
          generics = Syntax.traitMethodGenerics m
          params = Syntax.traitMethodParams m
          retType = Syntax.traitMethodReturnType m
          defBody = Syntax.traitMethodDefaultBody m
          genericsExpr = genericParamsToExpr generics
          paramsExpr = Serialization.parenListAdaptive (Lists.map methodParamToExpr params)
          retTypeExpr =
                  Optionals.cases retType Nothing (\t -> Just (Serialization.spaceSep [
                    Serialization.cst "->",
                    (typeToExpr t)]))
          header =
                  Serialization.spaceSep (Optionals.cat [
                    Just (Serialization.cst "fn"),
                    (Just (Serialization.cst name)),
                    genericsExpr,
                    (Just paramsExpr),
                    retTypeExpr])
      in (Optionals.cases defBody (Serialization.spaceSep [
        header,
        (Serialization.cst ";")]) (\body -> Serialization.spaceSep [
        header,
        (blockToExpr body)]))
-- | Serialize a trait associated type
traitTypeToExpr :: Syntax.TraitType -> Ast.Expr
traitTypeToExpr t =

      let name = Syntax.traitTypeName t
          bounds = Syntax.traitTypeBounds t
          def = Syntax.traitTypeDefault t
          boundsPart =
                  Logic.ifElse (Lists.null bounds) Nothing (Just (Serialization.spaceSep [
                    Serialization.cst ":",
                    (Serialization.cst (Strings.intercalate " + " (Lists.map (\b -> Serialization.printExpr (typeParamBoundToExpr b)) bounds)))]))
          defPart =
                  Optionals.cases def Nothing (\d -> Just (Serialization.spaceSep [
                    Serialization.cst "=",
                    (typeToExpr d)]))
      in (Serialization.spaceSep (Optionals.cat [
        Just (Serialization.cst "type"),
        (Just (Serialization.cst name)),
        boundsPart,
        defPart,
        (Just (Serialization.cst ";"))]))
-- | Serialize a tuple index expression
tupleIndexExprToExpr :: Syntax.TupleIndexExpr -> Ast.Expr
tupleIndexExprToExpr t =

      let tuple = Syntax.tupleIndexExprTuple t
          idx = Syntax.tupleIndexExprIndex t
      in (Serialization.cst (Strings.cat [
        Serialization.printExpr (expressionToExpr tuple),
        ".",
        (Literals.showInt32 idx)]))
-- | Serialize a tuple struct pattern
tupleStructPatternToExpr :: Syntax.TupleStructPattern -> Ast.Expr
tupleStructPatternToExpr tsp =

      let path = Syntax.tupleStructPatternPath tsp
          elems = Syntax.tupleStructPatternElements tsp
      in (Serialization.spaceSep [
        exprPathToExpr path,
        (Serialization.parenListAdaptive (Lists.map patternToExpr elems))])
-- | Serialize a type alias
typeAliasToExpr :: Syntax.TypeAlias -> Ast.Expr
typeAliasToExpr ta =

      let name = Syntax.typeAliasName ta
          generics = Syntax.typeAliasGenerics ta
          typ = Syntax.typeAliasType ta
          docC = Syntax.typeAliasDoc ta
          docPart = Optionals.cases docC [] (\d -> [
                Serialization.cst (toRustDocComment d)])
      in (Serialization.newlineSep (Lists.concat [
        docPart,
        [
          Serialization.spaceSep (Optionals.cat [
            Just (Serialization.cst "type"),
            (Just (Serialization.cst name)),
            (genericParamsToExpr generics),
            (Just (Serialization.cst "=")),
            (Just (typeToExpr typ)),
            (Just (Serialization.cst ";"))])]]))
-- | Serialize a type ascription expression
typeAscriptionExprToExpr :: Syntax.TypeAscriptionExpr -> Ast.Expr
typeAscriptionExprToExpr t =

      let expr = Syntax.typeAscriptionExprExpr t
          typ = Syntax.typeAscriptionExprType t
      in (Serialization.spaceSep [
        expressionToExpr expr,
        (Serialization.cst ":"),
        (typeToExpr typ)])
-- | Serialize a type parameter bound
typeParamBoundToExpr :: Syntax.TypeParamBound -> Ast.Expr
typeParamBoundToExpr bound =
    case bound of
      Syntax.TypeParamBoundTrait v0 -> typePathToExpr v0
      Syntax.TypeParamBoundLifetime v0 -> Serialization.cst (Strings.cat2 "'" (Syntax.lifetimeName v0))
-- | Serialize a type path
typePathToExpr :: Syntax.TypePath -> Ast.Expr
typePathToExpr tp =

      let global = Syntax.typePathGlobal tp
          segs = Syntax.typePathSegments tp
          prefix = Logic.ifElse global "::" ""
          segStrs = Lists.map (\s -> Serialization.printExpr (pathSegmentToExpr s)) segs
      in (Serialization.cst (Strings.cat2 prefix (Strings.intercalate "::" segStrs)))
-- | Serialize a Rust type
typeToExpr :: Syntax.Type -> Ast.Expr
typeToExpr typ =
    case typ of
      Syntax.TypePath_ v0 -> typePathToExpr v0
      Syntax.TypeReference v0 -> referenceTypeToExpr v0
      Syntax.TypeSlice v0 -> Serialization.bracketList Serialization.inlineStyle [
        typeToExpr v0]
      Syntax.TypeArray v0 ->
        let elem = Syntax.arrayTypeElement v0
            len = Syntax.arrayTypeLength v0
        in (Serialization.cst (Strings.cat [
          "[",
          (Serialization.printExpr (typeToExpr elem)),
          "; ",
          (Serialization.printExpr (expressionToExpr len)),
          "]"]))
      Syntax.TypeTuple v0 -> Serialization.parenListAdaptive (Lists.map typeToExpr v0)
      Syntax.TypeFnPointer v0 ->
        let params = Syntax.fnPointerTypeParams v0
            ret = Syntax.fnPointerTypeReturnType v0
        in (Serialization.spaceSep [
          Serialization.cst "fn",
          (Serialization.parenListAdaptive (Lists.map typeToExpr params)),
          (Serialization.cst "->"),
          (typeToExpr ret)])
      Syntax.TypeImplTrait v0 -> Serialization.spaceSep [
        Serialization.cst "impl",
        (Serialization.cst (Strings.intercalate " + " (Lists.map (\b -> Serialization.printExpr (typeParamBoundToExpr b)) v0)))]
      Syntax.TypeDynTrait v0 -> Serialization.spaceSep [
        Serialization.cst "dyn",
        (Serialization.cst (Strings.intercalate " + " (Lists.map (\b -> Serialization.printExpr (typeParamBoundToExpr b)) v0)))]
      Syntax.TypeInferred -> Serialization.cst "_"
      Syntax.TypeUnit -> Serialization.cst "()"
      Syntax.TypeNever -> Serialization.cst "!"
      Syntax.TypeRawPointer v0 ->
        let mut = Syntax.rawPointerTypeMutable v0
            t = Syntax.rawPointerTypeType v0
            kw = Logic.ifElse mut "*mut" "*const"
        in (Serialization.spaceSep [
          Serialization.cst kw,
          (typeToExpr t)])
      Syntax.TypeMacro v0 -> macroInvocationToExpr v0
-- | Serialize a unary expression
unaryExprToExpr :: Syntax.UnaryExpr -> Ast.Expr
unaryExprToExpr u =

      let op = Syntax.unaryExprOp u
          operand = Syntax.unaryExprOperand u
          opStr =
                  case op of
                    Syntax.UnaryOpNeg -> "-"
                    Syntax.UnaryOpNot -> "!"
      in (Serialization.cst (Strings.cat2 opStr (Serialization.printExpr (expressionToExpr operand))))
-- | Serialize a use declaration
useDeclarationToExpr :: Syntax.UseDeclaration -> Ast.Expr
useDeclarationToExpr use =

      let pub = Syntax.useDeclarationPublic use
          tree = Syntax.useDeclarationTree use
          pubKw = Logic.ifElse pub (Just (Serialization.cst "pub")) Nothing
      in (Serialization.spaceSep (Optionals.cat [
        pubKw,
        (Just (Serialization.cst "use")),
        (Just (useTreeToExpr tree)),
        (Just (Serialization.cst ";"))]))
-- | Serialize a use tree
useTreeToExpr :: Syntax.UseTree -> Ast.Expr
useTreeToExpr tree =
    case tree of
      Syntax.UseTreePath v0 -> Serialization.cst (Strings.intercalate "::" (Syntax.usePathSegments v0))
      Syntax.UseTreeRename v0 ->
        let path = Syntax.useRenamePath v0
            alias = Syntax.useRenameAlias v0
        in (Serialization.spaceSep [
          Serialization.cst (Strings.intercalate "::" path),
          (Serialization.cst "as"),
          (Serialization.cst alias)])
      Syntax.UseTreeGlob v0 -> Serialization.cst (Strings.cat2 (Strings.intercalate "::" v0) "::*")
      Syntax.UseTreeGroup v0 ->
        let prefix = Syntax.useGroupPrefix v0
            trees = Syntax.useGroupTrees v0
            prefixStr = Logic.ifElse (Lists.null prefix) "" (Strings.cat2 (Strings.intercalate "::" prefix) "::")
        in (Serialization.cst (Strings.cat [
          prefixStr,
          "{",
          (Strings.intercalate ", " (Lists.map (\t -> Serialization.printExpr (useTreeToExpr t)) trees)),
          "}"]))
-- | Serialize visibility to an optional expression
visibilityToExpr :: Syntax.Visibility -> Maybe Ast.Expr
visibilityToExpr vis =
    case vis of
      Syntax.VisibilityPublic -> Just (Serialization.cst "pub")
      Syntax.VisibilityCrate -> Just (Serialization.cst "pub(crate)")
      Syntax.VisibilityRestricted v0 -> Just (Serialization.cst (Strings.cat [
        "pub(in ",
        (Strings.intercalate "::" v0),
        ")"]))
      Syntax.VisibilityPrivate -> Nothing
-- | Serialize a where clause
whereClauseToExpr :: Syntax.WhereClause -> Ast.Expr
whereClauseToExpr wc =

      let preds = Syntax.whereClausePredicates wc
          predExprs =
                  Lists.map (\p ->
                    let typ = Syntax.wherePredicateType p
                        bounds = Syntax.wherePredicateBounds p
                    in (Serialization.spaceSep [
                      typeToExpr typ,
                      (Serialization.cst ":"),
                      (Serialization.cst (Strings.intercalate " + " (Lists.map (\b -> Serialization.printExpr (typeParamBoundToExpr b)) bounds)))])) preds
      in (Serialization.spaceSep [
        Serialization.cst "where",
        (Serialization.commaSep Serialization.inlineStyle predExprs)])
-- | Serialize a while expression
whileExprToExpr :: Syntax.WhileExpr -> Ast.Expr
whileExprToExpr w =

      let label = Syntax.whileExprLabel w
          cond = Syntax.whileExprCondition w
          body = Syntax.whileExprBody w
          labelPart = Optionals.cases label Nothing (\lbl -> Just (Serialization.cst (Strings.cat2 "'" (Strings.cat2 lbl ":"))))
          condExpr =
                  case cond of
                    Syntax.IfConditionBool v0 -> expressionToExpr v0
                    Syntax.IfConditionLet v0 ->
                      let pat = Syntax.letConditionPattern v0
                          expr = Syntax.letConditionExpr v0
                      in (Serialization.spaceSep [
                        Serialization.cst "let",
                        (patternToExpr pat),
                        (Serialization.cst "="),
                        (expressionToExpr expr)])
      in (Serialization.spaceSep (Optionals.cat [
        labelPart,
        (Just (Serialization.cst "while")),
        (Just condExpr),
        (Just (blockToExpr body))]))