/// <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); }
/// <inheritdoc /> protected override async Task <Result <Unit, IError> > Run( IStateMonad stateMonad, CancellationToken cancellationToken) { var elements = await Array.Run(stateMonad, cancellationToken); if (elements.IsFailure) { return(elements.ConvertFailure <Unit>()); } var currentState = stateMonad.GetState().ToImmutableDictionary(); async ValueTask <Result <Unit, IError> > Apply(T element, CancellationToken cancellation) { var scopedMonad = new ScopedStateMonad( stateMonad, currentState, new KeyValuePair <VariableName, object>(Variable, element !) ); var result = await Action.Run(scopedMonad, cancellation); return(result); } var finalResult = await elements.Value.ForEach(Apply, cancellationToken); return(finalResult); }
/// <inheritdoc /> protected override async Task <Result <Array <T>, IError> > Run( IStateMonad stateMonad, CancellationToken cancellationToken) { var entityStreamResult = await Array.Run(stateMonad, cancellationToken); if (entityStreamResult.IsFailure) { return(entityStreamResult.ConvertFailure <Array <T> >()); } var ignoreCaseResult = await IgnoreCase.Run(stateMonad, cancellationToken); if (ignoreCaseResult.IsFailure) { return(ignoreCaseResult.ConvertFailure <Array <T> >()); } IEqualityComparer <string> comparer = ignoreCaseResult.Value ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal; HashSet <string> usedKeys = new(comparer); var currentState = stateMonad.GetState().ToImmutableDictionary(); async IAsyncEnumerable <T> Filter(T element) { await using var scopedMonad = new ScopedStateMonad( stateMonad, currentState, new KeyValuePair <VariableName, object>(Variable, element !) ); var result = await KeySelector.Run(scopedMonad, cancellationToken) .Map(async x => await x.GetStringAsync()); if (result.IsFailure) { throw new ErrorException(result.Error); } if (usedKeys.Add(result.Value)) { yield return(element); } } var newStream = entityStreamResult.Value.SelectMany(Filter); return(newStream); }
/// <inheritdoc /> protected override async Task <Result <Array <T>, IError> > Run( IStateMonad stateMonad, CancellationToken cancellationToken) { var array = await Array.Run(stateMonad, cancellationToken); if (array.IsFailure) { return(array.ConvertFailure <Array <T> >()); } var descending = await Descending.Run(stateMonad, cancellationToken); if (descending.IsFailure) { return(descending.ConvertFailure <Array <T> >()); } Array <T> sortedArray; if (KeySelector == null) { sortedArray = array.Value.Sort(descending.Value); } else { var currentState = stateMonad.GetState().ToImmutableDictionary(); async ValueTask <string> GetKey(T entity, CancellationToken cancellation) { var scopedMonad = new ScopedStateMonad( stateMonad, currentState, new KeyValuePair <VariableName, object>(VariableName.Entity, entity !) ); var result = await KeySelector.Run(scopedMonad, cancellation) .Map(x => x.GetStringAsync()); if (result.IsFailure) { throw new ErrorException(result.Error); } return(result.Value); } sortedArray = array.Value.Sort(descending.Value, GetKey); } return(sortedArray); }
/// <inheritdoc /> protected override async Task <Result <Array <T>, IError> > Run( IStateMonad stateMonad, CancellationToken cancellationToken) { var entityStreamResult = await Array.Run(stateMonad, cancellationToken); if (entityStreamResult.IsFailure) { return(entityStreamResult.ConvertFailure <Array <T> >()); } var currentState = stateMonad.GetState().ToImmutableDictionary(); async IAsyncEnumerable <T> Filter(T record) { await using var scopedMonad = new ScopedStateMonad( stateMonad, currentState, new KeyValuePair <VariableName, object>(Variable, record !) ); var result = await Predicate.Run(scopedMonad, cancellationToken); if (result.IsFailure) { throw new ErrorException(result.Error); } if (result.Value) { yield return(record); } } var newStream = entityStreamResult.Value.SelectMany(Filter); return(newStream); }
/// <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())); }