namespace Invercargill { public class EnumerableInfo { public int? count { get; private set; } public Type enumerable_type { get; private set; } public Type element_type { get; private set; } public EnumerableCategory category { get; private set; } public Enumerable sources { get; private set; } public Enumerable ultimate_sources { get; private set; } public EnumerableInfo(int? count, Type enumerable_type, Type value_type, EnumerableCategory category, ReadOnlyCollection sources, Enumerable ultimate_sources) { this.count = count; this.enumerable_type = enumerable_type; this.element_type = value_type; this.category = category; this.sources = sources; this.ultimate_sources = ultimate_sources.cache(); } public EnumerableInfo.infer(Enumerable enumerable, EnumerableCategory category, Enumerable sources) { this.count = enumerable.peek_count(); this.enumerable_type = enumerable.get_type(); this.element_type = enumerable.element_type; this.category = category; this.sources = sources.select(s => s.get_info()).to_series().seal(); this.ultimate_sources = this.sources .where(s => s.ultimate_sources.no()) .concat(this.sources.select_many(s => s.ultimate_sources)); } public EnumerableInfo.infer_single(Enumerable enumerable, EnumerableCategory category, Enumerable source) { this.count = enumerable.peek_count(); this.enumerable_type = enumerable.get_type(); this.element_type = enumerable.element_type; this.category = category; var source_info = source.get_info(); this.sources = single(source_info); this.ultimate_sources = source_info.sources.any() ? source_info.ultimate_sources : single(source_info); } public EnumerableInfo.infer_ultimate(Enumerable enumerable, EnumerableCategory category) { this.count = enumerable.peek_count(); this.enumerable_type = enumerable.get_type(); this.element_type = enumerable.element_type; this.category = category; this.sources = empty(); this.ultimate_sources = this.sources; } } public enum EnumerableCategory { IN_MEMORY, EXTERNAL, COMPUTED, CACHED, PROXY; } }