/// <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); }