using Beam.Abstractions; using HtmlAgilityPack; namespace Beam.Dynamic; public class ManyComposeDataProviders : IManySelectionComposableDataProvider { public required IManySelectionComposableDataProvider[] SelectWith { get; init; } public required IManySelectionComposableDataProvider GetWith { get; init; } private ManyComposeDataProviders() {} public static ManyComposeDataProviders Create(IManySelectionComposableDataProvider selectWith, IManySelectionComposableDataProvider getWith) { return new ManyComposeDataProviders() { GetWith = getWith, SelectWith = [selectWith] }; } public static ManyComposeDataProviders Create(IManySelectionComposableDataProvider[] selectWiths, IManySelectionComposableDataProvider getWith) { return new ManyComposeDataProviders() { GetWith = getWith, SelectWith = selectWiths }; } /// /// Composes the data providers, first selecting a node with , then getting the data with . /// /// Throws when returns a null value. /// /// public T Get(HtmlDocument document) { var selected = SelectMany(document); if (selected is null) throw new Exception("Selection operation failed."); return GetWith.ManyGet(selected); } /// /// Uses the data provider to get the data from the supplied node. /// /// /// public T ManyGet(HtmlNode[] node) { return GetWith.ManyGet(node); } /// /// Uses the data provider to select a node from the supplied document. /// /// /// public HtmlNode[]? SelectMany(HtmlDocument doc) { var selected = SelectWith[0].SelectMany(doc); foreach(var provider in SelectWith.Skip(1)) { if (selected is null) return null; selected = provider.SelectMany(selected); } return selected; } /// /// Uses the data provider to select a node from the supplied document. /// /// /// public HtmlNode[]? SelectMany(HtmlNode[] node) { var selected = SelectWith[0].SelectMany(node); foreach(var provider in SelectWith.Skip(1)) { if (selected is null) return null; selected = provider.SelectMany(selected); } return selected; } }