loadFromRecord function

String loadFromRecord(
  1. SumTypeSpec spec
)

Implementation

String loadFromRecord(SumTypeSpec spec) => function(
      isStatic: true,
      type: [
        spec.sumTypeName,
        specialize(spec.typeParams.map((typeParam) => typeParam.name)),
      ].join(),
      name: "load",
      typeParams: [
        TypeParamSpec(
          name: "\$T",
          bound: [
            spec.recordIfaceName,
            specialize([
              "\$T",
              ...spec.typeParams.map((typeParam) => typeParam.name),
            ]),
          ].join(),
        ),
        ...spec.typeParams,
      ],
      posParams: [param(type: "\$T", name: "rec")],
      body: [
        spec.cases.map((expected) {
          final cond = spec.cases
              .map((other) => other == expected
                  ? "rec.${expected.name} != null"
                  : "rec.${other.name} == null")
              .join("&&");
          return [
            "if ($cond) {",
            "return ",
            if (!expected.type.requiresPayload && spec.typeParams.isEmpty)
              "const ",
            "${spec.sumTypeName}${specialize(spec.typeParams.map((param) => param.name))}.${expected.name}(",
            if (expected.type.isDirectlyRecursive)
              "load(rec.${expected.name}!)"
            else if (expected.type.requiresPayload)
              decorateArg(expected.parameterStyle, expected.parameterName,
                  "rec.${expected.name}!"),
            ");",
            "} else ",
          ].join();
        }).join(),
        "{ throw Exception(\"Cannot select a \$${spec.sumTypeName} case given \$rec\"); }",
      ],
    );