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
数値が低いほど優先度が高い.
- If property type is a class that implements
SerializeSignature
, the option value stores the result ofSerializeSignature.serialize
. - If property type is a class that implements
ToChainSpecific
, the option value stores the result of serializedToChainSpecific.toChain
. - If property type is Iterable, each option value stores the result of Iterable's element toString().
- 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);
}