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)
| 578 | // The last combination case indicates that an optional value in one case should be resolved |
| 579 | // to a non-optional value as |
| 580 | func (s optionalCompositionStep) combine(step compositionStep) compositionStep { |
| 581 | if step == nil { |
| 582 | // This is likely unreachable for an optional step, but worth adding as a safeguard |
| 583 | return s |
| 584 | } |
| 585 | ctx := s.ctx |
| 586 | trueCondition := ctx.NewLiteral(types.True) |
| 587 | if step.isOptional() { |
| 588 | // Introduce a ternary to capture the conditional return when combining a |
| 589 | // conditional optional with another optional. |
| 590 | if s.isConditional() { |
| 591 | return newOptionalCompositionStep(ctx, |
| 592 | trueCondition, |
| 593 | ctx.NewCall(operators.Conditional, |
| 594 | s.condition(), |
| 595 | s.expr(), |
| 596 | step.expr()), |
| 597 | ) |
| 598 | } |
| 599 | // When an optional is unconditionally combined with another optional, rely |
| 600 | // on the optional 'or' to fall-through from one optional to another. |
| 601 | if !isOptionalNone(step.expr()) { |
| 602 | return newOptionalCompositionStep(ctx, |
| 603 | trueCondition, |
| 604 | ctx.NewMemberCall("or", s.expr(), step.expr())) |
| 605 | } |
| 606 | // Otherwise, the current step 's' is unconditional and effectively prunes away |
| 607 | // the other input 'step'. |
| 608 | return s |
| 609 | } |
| 610 | if s.isConditional() { |
| 611 | // Introduce a ternary to capture the conditional return while wrapping the |
| 612 | // non-optional result from a lower step into an optional value. |
| 613 | return newOptionalCompositionStep(ctx, |
| 614 | trueCondition, |
| 615 | ctx.NewCall(operators.Conditional, |
| 616 | s.condition(), |
| 617 | s.expr(), |
| 618 | ctx.NewCall("optional.of", step.expr()))) |
| 619 | } |
| 620 | // If the current step is unconditional and the step is non-optional, attempt |
| 621 | // to convert to the optional step 's' to a non-optional value using `orValue` |
| 622 | // with the 'step' expression value. |
| 623 | return newNonOptionalCompositionStep(ctx, |
| 624 | trueCondition, |
| 625 | ctx.NewMemberCall("orValue", s.expr(), step.expr()), |
| 626 | ) |
| 627 | } |
| 628 | |
| 629 | func isOptionalNone(e ast.Expr) bool { |
| 630 | return e.Kind() == ast.CallKind && |
nothing calls this directly
no test coverage detected