-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: fluent builders for linear pipelines (#67)
- support for mapper, filter, plucker, splitter - support for sink and source - support for aggregators and parsers
- Loading branch information
Showing
67 changed files
with
1,155 additions
and
223 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Reflection.PortableExecutable; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Streamistry.Pipes.Aggregators; | ||
|
||
namespace Streamistry.Fluent; | ||
internal class AggregatorBuilder<TInput, TAccumulate, TOutput> | ||
{ | ||
protected IPipeBuilder<TInput> Upstream { get; } | ||
|
||
public AggregatorBuilder(IPipeBuilder<TInput> upstream) | ||
=> Upstream = upstream; | ||
|
||
public SpecializedAggregatorBuilder<TInput, TAccumulate, TOutput> AsMax() | ||
=> new SpecializedAggregatorBuilder<TInput, TAccumulate, TOutput>(Upstream, typeof(Max<>), [typeof(TInput)]); | ||
public SpecializedAggregatorBuilder<TInput, TAccumulate, TOutput> AsMin() | ||
=> new SpecializedAggregatorBuilder<TInput, TAccumulate, TOutput>(Upstream, typeof(Min<>), [typeof(TInput)]); | ||
public SpecializedAggregatorBuilder<TInput, TAccumulate, TOutput> AsAverage() | ||
=> new SpecializedAggregatorBuilder<TInput, TAccumulate, TOutput>(Upstream, typeof(Average<,>), [typeof(TInput), typeof(TOutput)]); | ||
public SpecializedAggregatorBuilder<TInput, TAccumulate, TOutput> AsMedian() | ||
=> new SpecializedAggregatorBuilder<TInput, TAccumulate, TOutput>(Upstream, typeof(Median<,>), [typeof(TInput), typeof(TOutput)]); | ||
public SpecializedAggregatorBuilder<TInput, TAccumulate, TOutput> AsSum() | ||
=> new SpecializedAggregatorBuilder<TInput, TAccumulate, TOutput>(Upstream, typeof(Sum<,>), [typeof(TInput), typeof(TOutput)]); | ||
public SpecializedAggregatorBuilder<TInput, TAccumulate, TOutput> AsCount() | ||
=> new SpecializedAggregatorBuilder<TInput, TAccumulate, TOutput>(Upstream, typeof(Count<,>), [typeof(TInput), typeof(TOutput)]); | ||
|
||
} | ||
|
||
internal class SpecializedAggregatorBuilder<TInput, TAccumulate, TOutput> : PipeElementBuilder<TInput, TOutput> | ||
{ | ||
protected Type Type { get; } | ||
protected Type[] GenericTypeParameters { get; } = [typeof(int)]; | ||
public SpecializedAggregatorBuilder(IPipeBuilder<TInput> upstream, Type type, Type[] genericTypeParameters) | ||
: base(upstream) | ||
=> (Type, GenericTypeParameters) = (type, genericTypeParameters); | ||
|
||
public override IChainablePort<TOutput> OnBuildPort() | ||
{ | ||
var t = Type.MakeGenericType(GenericTypeParameters); | ||
return (IChainablePort<TOutput>)Activator.CreateInstance(t, Upstream.BuildPort(), null)!; | ||
} | ||
} | ||
|
||
internal class UniversalAggregatorBuilder<TInput, TAccumulate, TOutput> : PipeElementBuilder<TInput, TOutput> | ||
{ | ||
protected Func<TAccumulate?, TInput?, TAccumulate?>? Accumulator { get; } | ||
protected Func<TAccumulate?, TOutput?>? Selector { get; set; } = x => (TOutput?)Convert.ChangeType(x, typeof(TOutput)); | ||
protected TAccumulate? Seed { get; set; } = default; | ||
|
||
public UniversalAggregatorBuilder(IPipeBuilder<TInput> upstream, Func<TAccumulate?, TInput?, TAccumulate?> accumulator) | ||
: base(upstream) | ||
=> (Accumulator) = (accumulator); | ||
|
||
public UniversalAggregatorBuilder<TInput, TAccumulate, TOutput> WithSelector(Func<TAccumulate?, TOutput?>? selector) | ||
{ | ||
Selector = selector; | ||
return this; | ||
} | ||
|
||
public UniversalAggregatorBuilder<TInput, TAccumulate, TOutput> WithSeed(TAccumulate? seed) | ||
{ | ||
Seed = seed; | ||
return this; | ||
} | ||
|
||
public override IChainablePort<TOutput> OnBuildPort() | ||
=> new Aggregator<TInput, TAccumulate, TOutput>( | ||
Upstream.BuildPort() | ||
, Accumulator ?? throw new InvalidOperationException() | ||
, Selector ?? throw new InvalidOperationException() | ||
, Seed | ||
); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Linq.Expressions; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace Streamistry.Fluent; | ||
|
||
internal abstract class BasePipeBuilder<TOutput> : IPipeBuilder<TOutput> | ||
{ | ||
protected IChainablePort<TOutput>? Instance { get; set; } | ||
|
||
public abstract IChainablePort<TOutput> OnBuildPort(); | ||
|
||
public IChainablePort<TOutput> BuildPort() | ||
=> Instance ??= OnBuildPort(); | ||
|
||
public Pipeline Build() | ||
{ | ||
BuildPort(); | ||
return Instance!.Pipe.Pipeline!; | ||
} | ||
|
||
public SinkBuilder<TOutput> Sink() | ||
=> new(this); | ||
|
||
public FilterBuilder<TOutput> Filter(Func<TOutput?, bool>? function) | ||
=> new(this, function); | ||
public MapperBuilder<TOutput, TNext> Map<TNext>(Func<TOutput?, TNext?>? function) | ||
=> new(this, function); | ||
public PluckerBuilder<TOutput, TNext> Pluck<TNext>(Expression<Func<TOutput, TNext?>> expr) | ||
=> new(this, expr); | ||
public SplitterBuilder<TOutput, TNext> Split<TNext>(Func<TOutput?, TNext[]?>? function) | ||
=> new(this, function); | ||
|
||
public UniversalAggregatorBuilder<TOutput, TAccumulate, TNext> Aggregate<TAccumulate, TNext>(Func<TAccumulate?, TOutput?, TAccumulate?> accumulator) | ||
=> new(this, accumulator); | ||
public UniversalAggregatorBuilder<TOutput, TNext, TNext> Aggregate<TNext>(Func<TNext?, TOutput?, TNext?> accumulator) | ||
=> new(this, accumulator); | ||
public UniversalAggregatorBuilder<TOutput, TOutput, TOutput> Aggregate(Func<TOutput?, TOutput?, TOutput?> accumulator) | ||
=> new(this, accumulator); | ||
public AggregatorBuilder<TOutput, TOutput, TOutput> Aggregate() | ||
=> new(this); | ||
|
||
public ParserBuilder<TOutput, TNext> Parse<TNext>(ParserDelegate<TOutput, TNext> parser) | ||
=> new(this, parser); | ||
public ParserBuilder<TOutput> Parse() | ||
=> new(this); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace Streamistry.Fluent; | ||
internal class FilterBuilder<TInput> : PipeElementBuilder<TInput, TInput>, IPipeBuilder<TInput> | ||
{ | ||
protected Func<TInput?, bool>? Function { get; } | ||
|
||
public FilterBuilder(IPipeBuilder<TInput> upstream, Func<TInput?, bool>? function) | ||
:base(upstream) | ||
=> (Function) = (function); | ||
|
||
public override IChainablePort<TInput> OnBuildPort() | ||
=> new Filter<TInput>( | ||
Upstream.BuildPort() | ||
, Function ?? throw new InvalidOperationException() | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace Streamistry.Fluent; | ||
internal interface IPipeBuilder<T> : IBuilder<IChainablePort<T>> | ||
{ } | ||
|
||
internal interface IBuilder<T> | ||
{ | ||
T BuildPort(); | ||
T OnBuildPort(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace Streamistry.Fluent; | ||
internal class MapperBuilder<TInput, TOutput> : PipeElementBuilder<TInput, TOutput> | ||
{ | ||
protected Func<TInput?, TOutput?>? Function { get; set; } | ||
|
||
public MapperBuilder(IPipeBuilder<TInput> upstream, Func<TInput?, TOutput?>? function) | ||
: base(upstream) | ||
=> (Function) = (function); | ||
|
||
public override IChainablePort<TOutput> OnBuildPort() | ||
=> new Mapper<TInput, TOutput>( | ||
Upstream.BuildPort() | ||
, Function ?? throw new InvalidOperationException() | ||
); | ||
} |
Oops, something went wrong.