/// <inheritdoc /> protected override async Task <Result <Array <Entity>, IError> > Run( IStateMonad stateMonad, CancellationToken cancellationToken) { var entityStreamResult = await EntityStream.Run(stateMonad, cancellationToken); if (entityStreamResult.IsFailure) { return(entityStreamResult.ConvertFailure <Array <Entity> >()); } var currentState = stateMonad.GetState().ToImmutableDictionary(); async ValueTask <Entity> Action(Entity record) { await using var scopedMonad = new ScopedStateMonad( stateMonad, currentState, new KeyValuePair <VariableName, object>(Variable, record) ); var result = await Function.Run(scopedMonad, cancellationToken); if (result.IsFailure) { throw new ErrorException(result.Error); } return(result.Value); } var newStream = entityStreamResult.Value.SelectAwait(Action); return(newStream); }
public async Task ScopedStateMonadShouldDisposeVariablesThatItRemoves() { var repo = new MockRepository(MockBehavior.Strict); var sd = repo.Create <IDoubleDisposable>(); var monad1 = CreateMonad(repo); var scopedMonad = new ScopedStateMonad( monad1, ImmutableDictionary <VariableName, object> .Empty ); sd.Setup(x => x.DisposeAsync(scopedMonad)).Returns(Task.CompletedTask); sd.Setup(x => x.Dispose()); await scopedMonad.SetVariableAsync(new VariableName("V"), sd.Object, false, null); await scopedMonad.RemoveVariableAsync(new VariableName("V"), true, null); repo.VerifyAll(); }
public async Task ScopedStateMonadShouldDisposeVariablesWhenItIsDisposed() { var repo = new MockRepository(MockBehavior.Strict); var sd = repo.Create <IDoubleDisposable>(); var monad1 = CreateMonad(repo); var scopedMonad = new ScopedStateMonad( monad1, ImmutableDictionary <VariableName, object> .Empty ); // ReSharper disable once AccessToDisposedClosure sd.Setup(x => x.DisposeAsync(scopedMonad)).Returns(Task.CompletedTask); sd.Setup(x => x.Dispose()); await scopedMonad.SetVariableAsync(new VariableName("V"), sd.Object, false, null); await scopedMonad.DisposeAsync(); repo.VerifyAll(); }
/// <inheritdoc /> protected override async Task <Result <StringStream, IError> > Run( IStateMonad stateMonad, CancellationToken cancellationToken) { var stringResult = await String.Run(stateMonad, cancellationToken).Map(x => x.GetStringAsync()); if (stringResult.IsFailure) { return(stringResult.ConvertFailure <StringStream>()); } var patternResult = await Pattern.Run(stateMonad, cancellationToken).Map(x => x.GetStringAsync()); if (patternResult.IsFailure) { return(patternResult.ConvertFailure <StringStream>()); } var ignoreCaseResult = await IgnoreCase.Run(stateMonad, cancellationToken); if (ignoreCaseResult.IsFailure) { return(ignoreCaseResult.ConvertFailure <StringStream>()); } var currentState = stateMonad.GetState().ToImmutableDictionary(); var regexOptions = RegexOptions.None; if (ignoreCaseResult.Value) { regexOptions |= RegexOptions.IgnoreCase; } var regex = new Regex(patternResult.Value, regexOptions); var input = stringResult.Value; var sb = new StringBuilder(); var lastIndex = 0; foreach (Match match in regex.Matches(input)) { sb.Append(input, lastIndex, match.Index - lastIndex); await using var scopedMonad = new ScopedStateMonad( stateMonad, currentState, new KeyValuePair <VariableName, object>(Variable, new StringStream(match.Value)) ); var result = await Function.Run(scopedMonad, cancellationToken) .Map(x => x.GetStringAsync()); if (result.IsFailure) { return(result.ConvertFailure <StringStream>()); } sb.Append(result.Value); lastIndex = match.Index + match.Length; } sb.Append(input, lastIndex, input.Length - lastIndex); return(new StringStream(sb.ToString())); }
/// <inheritdoc /> protected override async Task <Result <Unit, IError> > Run( IStateMonad stateMonad, CancellationToken cancellationToken) { var sclResult = await SCL.Run(stateMonad, cancellationToken).Map(x => x.GetStringAsync()); if (sclResult.IsFailure) { return(sclResult.ConvertFailure <Unit>()); } List <VariableName> variablesToExport; if (Export is null) { variablesToExport = new List <VariableName>(); } else { var exportResult = await Export.Run(stateMonad, cancellationToken) .Bind(x => x.GetElementsAsync(cancellationToken)); if (exportResult.IsFailure) { return(exportResult.ConvertFailure <Unit>()); } variablesToExport = exportResult.Value.Select(x => x.GetString()) .Select(x => new VariableName(x)) .ToList(); } var stepResult = SCLParsing.TryParseStep(sclResult.Value) .Bind(x => x.TryFreeze(TypeReference.Unit.Instance, stateMonad.StepFactoryStore)); if (stepResult.IsFailure) { return(stepResult.ConvertFailure <Unit>()); } await using var monad2 = new ScopedStateMonad( stateMonad, ImmutableDictionary <VariableName, object> .Empty ); await stepResult.Value.Run <Unit>(monad2, cancellationToken); foreach (var variable in variablesToExport) { var value = monad2.GetVariable <object>(variable); var valueV = value.IsSuccess ? value.Value : null; await monad2.RemoveVariableAsync( variable, false, this ); //Remove the variable to prevent it being disposed await stateMonad.SetVariableAsync(variable, valueV, true, this); } return(Unit.Default); }