toChain method

Danger<Chain, ChainSyntaxException> toChain()
inherited

ChainHeadSignature.chainHead parsed as a head.
bool property parsed as a flag.
other property parsed as a option

数値が低いほど優先度が高い.

  1. If property type is a class that implements SerializeSignature, the option value stores the result of SerializeSignature.serialize.
  2. If property type is a class that implements ToChainSpecific, the option value stores the result of serialized ToChainSpecific.toChain.
  3. If property type is Iterable, each option value stores the result of Iterable's element toString().
  4. If property type is other, the option value stores the result of toString().

Implementation

Danger<Chain, ChainSyntaxException> toChain() {

    final log = Log(classLocation: runtimeType, functionLocation: 'toChain');

    final List<Option> optionList = [];
    final List<Flag> flagList = [];

    for (final entry in properties.entries) {

        final value = entry.value;

        if (value is bool) {

            // false の場合 その flag は追加しない.
            if (value == false) continue;

            final flagNameResult = FlagNameArgument.result('-' + entry.key);
            log.add(flagNameResult);
            if (flagNameResult is! Success<FlagNameArgument, ChainSyntaxExceptionEH>) return Failure(flagNameResult.asException, log);

            final result = Flag(flagNameResult.wrapped);

            flagList.add(result);

            continue;

        }

        final optionNameResult = OptionNameArgument.result('--' + entry.key);
        log.add(optionNameResult);
        if (optionNameResult is! Success<OptionNameArgument, ChainSyntaxExceptionEG>) return Failure(optionNameResult.asException, log);

        late final List<String> valueList;

        // option
        switch (value) {
        // iterable より先に SerializeSignature を判定する.
        // 出なければ SerializeSignature を実装した Iterable class が toString() してしまう.
        // user によって決めれる SerializeSignature を第一優先とする.
        case SerializeSignature(): valueList = [value.serialize()];
        case ToChainSpecific():
            final result = value.toChain();
            log.add(result);
            if (result is! Success<Chain, ChainSyntaxException>) return Failure(result.asException, log);
            valueList = [result.wrapped.serialize()];
        // multiple
        // 各々の element に対して SerializeSignature の分岐は可能だがめんどくさい.
        // xxxStructList が来る前提とし それは 上の case で処理.
        case Iterable(): valueList = List.generate(value.length, (index) => value.elementAt(index).toString());
        // single String と num もここに含まれる.
        case _: valueList = [value.toString()];
        }

        // すべての option value を chain の option value として 有効にするため escape 処理を行う.
        final valueArgumentListResult = ValueArgumentList.fromPrimitiveWithEscape(valueList);
        log.add(valueArgumentListResult);


        final result = Option(optionNameResult.wrapped, valueArgumentListResult.wrapped);

        optionList.add(result);

    }

    final headNameResult = HeadNameArgument.result(chainHead);
    log.add(headNameResult);
    if (headNameResult is! Success<HeadNameArgument, ChainSyntaxExceptionEF>) return Failure(headNameResult.asException, log);
    final headBox = Head(headNameResult.wrapped);

    final result = Chain.result(headBox, optionList, flagList);
    log.add(result);

    return Danger.fromDanger(result, log);

}