72 lines
2.3 KiB
C#
72 lines
2.3 KiB
C#
using System.Text.Json.Nodes;
|
|
using w4c_workflows.Models.Nodes;
|
|
|
|
namespace w4c_workflows.Services.Nodes.Executors;
|
|
|
|
/// <summary>
|
|
/// Merge node. Combines two input ports into one:
|
|
/// - <c>append</c> — input 0 items then input 1 items;
|
|
/// - <c>chooseBranch</c> — the items of the first non-empty input;
|
|
/// - <c>combineByPosition</c> — pair items by index and shallow-merge their
|
|
/// fields (input 1 overrides input 0); items past the shorter input pass
|
|
/// through unchanged.
|
|
/// Runs in all-items mode because it has more than one input port.
|
|
/// </summary>
|
|
public sealed class MergeNodeExecutor : INodeExecutor
|
|
{
|
|
public string Type => "core.merge";
|
|
|
|
public Task<NodeExecutionOutcome> RunAsync(NodeExecutionContext context, CancellationToken ct)
|
|
{
|
|
var first = context.Input(0);
|
|
var second = context.Input(1);
|
|
var mode = context.Parameters["mode"] is JsonValue value && value.TryGetValue<string>(out var text)
|
|
? text
|
|
: "append";
|
|
|
|
var items = mode switch
|
|
{
|
|
"chooseBranch" => first.Count > 0 ? first.ToList() : second.ToList(),
|
|
"combineByPosition" => CombineByPosition(first, second),
|
|
_ => first.Concat(second).ToList(),
|
|
};
|
|
|
|
return Task.FromResult(NodeExecutionOutcome.Single(items));
|
|
}
|
|
|
|
private static List<FlowItem> CombineByPosition(
|
|
IReadOnlyList<FlowItem> first, IReadOnlyList<FlowItem> second)
|
|
{
|
|
var merged = new List<FlowItem>(Math.Max(first.Count, second.Count));
|
|
for (var i = 0; i < first.Count || i < second.Count; i++)
|
|
{
|
|
var left = i < first.Count ? first[i] : null;
|
|
var right = i < second.Count ? second[i] : null;
|
|
|
|
if (left == null)
|
|
{
|
|
merged.Add(right!);
|
|
continue;
|
|
}
|
|
if (right == null)
|
|
{
|
|
merged.Add(left);
|
|
continue;
|
|
}
|
|
|
|
var json = (JsonObject)left.Json.DeepClone();
|
|
foreach (var (name, node) in right.Json)
|
|
json[name] = node?.DeepClone();
|
|
|
|
merged.Add(new FlowItem
|
|
{
|
|
Json = json,
|
|
Binary = left.Binary ?? right.Binary,
|
|
Origin = left.Origin ?? right.Origin,
|
|
});
|
|
}
|
|
|
|
return merged;
|
|
}
|
|
}
|