/// <summary> /// Creates formatting function for sequence which applies provided formatter to every sequence item /// and joins results with <paramref name="glue"/>. /// </summary> /// <param name="fmt">Formats individual sequence elements.</param> /// <param name="glue">Joins formatter results applied to subsequent items.</param> /// <typeparam name="T">Type of collection elements.</typeparam> public static Formatter <IEnumerable <T> > Collect <T>(Formatter <T> fmt, Writer glue = null) { glue = glue ?? WriteWhitespace; return(seq => seq .Select(fmt.Invoke) .Aggregate((a, b) => IsEmpty(b) ? a : Writers.Sum(a, glue, b))); }
/// <summary> /// Combines 2 formatting function into one by applying them in sequence and executing <paramref name="separator"/> /// <see cref="Writer"/> in between. If any <see cref="Formatter{T}"/> results in empty <see cref="Writer"/> /// than only one (the other) will be applied. /// </summary> /// <param name="first"><see cref="Formatter{T}"/> function applied first.</param> /// <param name="second"><see cref="Formatter{T}"/> function applied second.</param> /// <param name="separator"><see cref="Writer"/> function applied in between.</param> /// <typeparam name="T">Formatted value type.</typeparam> public static Formatter <T> Join <T>(Formatter <T> first, Formatter <T> second, Writer separator) { return(obj => { var firstWriter = first?.Invoke(obj); var secondWriter = second?.Invoke(obj); return IsEmpty(secondWriter) ? firstWriter : IsEmpty(firstWriter) ? secondWriter : Writers.Sum(firstWriter, separator, secondWriter); }); }