Ejemplo n.º 1
0
        /// <inheritdoc />
        protected override async Task <Result <Unit, IError> > Run(
            IStateMonad stateMonad,
            CancellationToken cancellationToken)
        {
            var variableName = VariableName.Index;

            var from = await From.Run(stateMonad, cancellationToken);

            if (from.IsFailure)
            {
                return(from.ConvertFailure <Unit>());
            }

            var to = await To.Run(stateMonad, cancellationToken);

            if (to.IsFailure)
            {
                return(to.ConvertFailure <Unit>());
            }

            var increment = await Increment.Run(stateMonad, cancellationToken);

            if (increment.IsFailure)
            {
                return(increment.ConvertFailure <Unit>());
            }

            var currentValue = from.Value;

            var setResult = await stateMonad.SetVariableAsync(variableName, currentValue, false, this);

            if (setResult.IsFailure)
            {
                return(setResult.ConvertFailure <Unit>());
            }

            if (increment.Value == 0)
            {
                return(new SingleError(new ErrorLocation(this), ErrorCode.DivideByZero));
            }

            while (increment.Value > 0 ? currentValue <= to.Value : currentValue >= to.Value)
            {
                var r = await Action.Run(stateMonad, cancellationToken);

                if (r.IsFailure)
                {
                    return(r);
                }

                var currentValueResult = stateMonad.GetVariable <int>(variableName)
                                         .MapError(e => e.WithLocation(this));

                if (currentValueResult.IsFailure)
                {
                    return(currentValueResult.ConvertFailure <Unit>());
                }

                currentValue  = currentValueResult.Value;
                currentValue += increment.Value;

                var setResult2 = await stateMonad.SetVariableAsync(
                    variableName,
                    currentValue,
                    false,
                    this
                    );

                if (setResult2.IsFailure)
                {
                    return(setResult.ConvertFailure <Unit>());
                }
            }

            await stateMonad.RemoveVariableAsync(VariableName.Index, false, this);

            return(Unit.Default);
        }