vorteil/direktiv

View on GitHub
pkg/flow/states/switch.go

Summary

Maintainability
A
45 mins
Test Coverage
package states

import (
    "context"
    "errors"
    "fmt"

    derrors "github.com/direktiv/direktiv/pkg/flow/errors"
    log "github.com/direktiv/direktiv/pkg/flow/internallogger"
    "github.com/direktiv/direktiv/pkg/model"
)

//nolint:gochecknoinits
func init() {
    RegisterState(model.StateTypeSwitch, Switch)
}

type switchLogic struct {
    *model.SwitchState
    Instance
}

// Switch initializes the logic for executing a 'switch' state in a Direktiv workflow instance.
func Switch(instance Instance, state model.State) (Logic, error) {
    s, ok := state.(*model.SwitchState)
    if !ok {
        return nil, derrors.NewInternalError(errors.New("bad state object"))
    }

    sl := new(switchLogic)
    sl.Instance = instance
    sl.SwitchState = s

    return sl, nil
}

// Run implements the Run function for the Logic interface.
//
// The 'switch' evaluates one or more conditions against the instance data to determine which
// transform and which transition to use. The logic only needs to be scheduled in once. The
// most likely way for the logic to fail is a JQ error against the instance data.
func (logic *switchLogic) Run(ctx context.Context, wakedata []byte) (*Transition, error) {
    err := scheduleOnce(logic, wakedata)
    if err != nil {
        return nil, err
    }

    for i, condition := range logic.Conditions {
        var x interface{}
        x, err = jqOne(logic.GetInstanceData(), condition.Condition) //nolint:contextcheck
        if err != nil {
            return nil, derrors.NewInternalError(fmt.Errorf("switch condition %d condition failed to run: %w", i, err))
        }

        if truth(x) {
            logic.Log(ctx, log.Info, "Switch condition %d succeeded", i)

            return &Transition{
                Transform: condition.Transform,
                NextState: condition.Transition,
            }, nil
        }
    }

    logic.Log(ctx, log.Info, "No switch conditions succeeded")

    return &Transition{
        Transform: logic.DefaultTransform,
        NextState: logic.DefaultTransition,
    }, nil
}