combine assembles a new compositionStep from the target output step an an input output step. optional.combine(optional) // optional (optional && conditional).combine(non-optional) // optional (optional && unconditional).combine(non-optional) // non-optional The last combination case indicates that
(step compositionStep)
| 531 | // The last combination case indicates that an optional value in one case should be resolved |
| 532 | // to a non-optional value as |
| 533 | func (s optionalCompositionStep) combine(step compositionStep) compositionStep { |
| 534 | if step == nil { |
| 535 | // This is likely unreachable for an optional step, but worth adding as a safeguard |
| 536 | return s |
| 537 | } |
| 538 | ctx := s.ctx |
| 539 | trueCondition := ctx.NewLiteral(types.True) |
| 540 | if step.isOptional() { |
| 541 | // Introduce a ternary to capture the conditional return when combining a |
| 542 | // conditional optional with another optional. |
| 543 | if s.isConditional() { |
| 544 | return newOptionalCompositionStep(ctx, |
| 545 | trueCondition, |
| 546 | ctx.NewCall(operators.Conditional, |
| 547 | s.condition(), |
| 548 | s.expr(), |
| 549 | step.expr()), |
| 550 | ) |
| 551 | } |
| 552 | // When an optional is unconditionally combined with another optional, rely |
| 553 | // on the optional 'or' to fall-through from one optional to another. |
| 554 | if !isOptionalNone(step.expr()) { |
| 555 | return newOptionalCompositionStep(ctx, |
| 556 | trueCondition, |
| 557 | ctx.NewMemberCall("or", s.expr(), step.expr())) |
| 558 | } |
| 559 | // Otherwise, the current step 's' is unconditional and effectively prunes away |
| 560 | // the other input 'step'. |
| 561 | return s |
| 562 | } |
| 563 | if s.isConditional() { |
| 564 | // Introduce a ternary to capture the conditional return while wrapping the |
| 565 | // non-optional result from a lower step into an optional value. |
| 566 | return newOptionalCompositionStep(ctx, |
| 567 | trueCondition, |
| 568 | ctx.NewCall(operators.Conditional, |
| 569 | s.condition(), |
| 570 | s.expr(), |
| 571 | ctx.NewCall("optional.of", step.expr()))) |
| 572 | } |
| 573 | // If the current step is unconditional and the step is non-optional, attempt |
| 574 | // to convert to the optional step 's' to a non-optional value using `orValue` |
| 575 | // with the 'step' expression value. |
| 576 | return newNonOptionalCompositionStep(ctx, |
| 577 | trueCondition, |
| 578 | ctx.NewMemberCall("orValue", s.expr(), step.expr()), |
| 579 | ) |
| 580 | } |
| 581 | |
| 582 | func isOptionalNone(e ast.Expr) bool { |
| 583 | return e.Kind() == ast.CallKind && |
nothing calls this directly
no test coverage detected