예제 #1
0
 private static void TryWriteFootnotes(this StandardStreamWriter stream, string?footnotes)
 {
     if (!string.IsNullOrWhiteSpace(footnotes))
     {
         stream.WithForegroundColor(ConsoleColor.DarkGray, (o) => o.WriteLine(TextUtils.AdjustNewLines(footnotes)));
         stream.WriteLine();
     }
 }
예제 #2
0
        private static void WriteTableHeader(this StandardStreamWriter stream, IEnumerable <string> headers, int[] columnWidths, int totalWidth)
        {
            if (headers.Any())
            {
                for (int i = 0; i < columnWidths.Length; ++i)
                {
                    string header      = headers.ElementAtOrDefault(i) ?? string.Empty;
                    int    targetWidth = columnWidths[i];

                    stream.Write(' ');
                    stream.WithForegroundColor(ConsoleColor.DarkYellow, (o) => o.Write(header.PadRight(targetWidth)));

                    if (i + 1 < columnWidths.Length)
                    {
                        stream.WithForegroundColor(ConsoleColor.Magenta, (o) => o.Write(" |"));
                    }
                }
                stream.WriteLine();

                //Write middle line
                stream.WriteBorder(totalWidth);
            }
        }
예제 #3
0
        /// <summary>
        /// Writes a table to the console.
        /// </summary>
        public static void Write <TKey, TElement>(StandardStreamWriter stream,
                                                  IEnumerable <IGrouping <TKey, TElement> > collection,
                                                  IEnumerable <string> headers,
                                                  string?footnotes,
                                                  params Expression <Func <TElement, string> >[] values)
        {
            int columnsCount = values.Length;

            Func <TElement, string>[] columnFunctions = values.Select(x => x.Compile())
                                                        .ToArray();

            int[] columnWidths = (from cf in columnFunctions
                                  let x = (collection.Any() ? collection.SelectMany(x => x).Select(cf).Max(x => x.Length) : 0)
                                          select x).ToArray();

            AdjustColumnWidths(headers, columnsCount, columnWidths);

            int totalWidth = columnWidths.Sum() - 1 + (columnsCount) * 3;

            //Write top border
            stream.WriteBorder(totalWidth);
            stream.WriteTableHeader(headers, columnWidths, totalWidth);

            foreach (IGrouping <TKey, TElement> group in collection)
            {
                TKey groupKey     = group.Key;
                int  countInGroup = group.Count();

                stream.WriteBorder(totalWidth, '-');
                stream.WithForegroundColor(ConsoleColor.DarkYellow, (o) => o.WriteLine($" {groupKey} ({countInGroup}) ".PadBoth(totalWidth)));
                stream.WriteBorder(totalWidth, '-');

                //Write table body
                stream.WriteTableBody(group, columnFunctions, columnWidths);
            }

            // Write bottom border and try write footnotes
            stream.WriteBorder(totalWidth);
            stream.TryWriteFootnotes(footnotes);
        }
예제 #4
0
        private static void WriteTableBody <TElement>(this StandardStreamWriter stream, IEnumerable <TElement> collection, Func <TElement, string>[] columnFunctions, int[] columnWidths)
        {
            foreach (TElement item in collection)
            {
                for (int i = 0; i < columnWidths.Length; ++i)
                {
                    Func <TElement, string> column = columnFunctions[i];
                    stream.Write(' ');

                    string value       = columnFunctions[i].Invoke(item);
                    int    targetWidth = columnWidths[i];

                    stream.Write(value.PadRight(targetWidth));

                    if (i + 1 < columnWidths.Length)
                    {
                        stream.WithForegroundColor(ConsoleColor.Magenta, (o) => o.Write(" |"));
                    }
                }

                stream.WriteLine();
            }
        }
예제 #5
0
        private static void WriteException(this StandardStreamWriter output, Exception exception, int indentLevel)
        {
            Type exceptionType = exception.GetType();

            string indentationShared = new string(' ', 4 * indentLevel);
            string indentationLocal  = new string(' ', 2);

            // Fully qualified exception type
            output.Write(indentationShared);
            output.WithForegroundColor(ConsoleColor.DarkGray, (o) =>
            {
                o.Write(exceptionType.Namespace);
                o.Write('.');
            });
            output.WithForegroundColor(ConsoleColor.White, (o) => o.Write(exceptionType.Name));
            output.Write(": ");

            // Exception message
            output.WithForegroundColor(ConsoleColor.Red, (o) => o.WriteLine(exception.Message));

            // Recurse into inner exceptions
            if (exception.InnerException is not null)
            {
                output.WriteException(exception.InnerException, indentLevel + 1);
            }

            if (exception.StackTrace is null)
            {
                return;
            }

            // Try to parse and pretty-print the stack trace
            try
            {
                foreach (StackFrame stackFrame in StackTraceParser.ParseMany(exception.StackTrace))
                {
                    output.Write(indentationShared);
                    output.Write(indentationLocal);
                    output.WithForegroundColor(ConsoleColor.Green, (o) => o.Write("at "));

                    // "Typin.Demo.Commands.BookAddCommand."
                    output.WithForegroundColor(ConsoleColor.DarkGray, (o) =>
                    {
                        o.Write(stackFrame.ParentType);
                        o.Write('.');
                    });

                    // "ExecuteAsync"
                    output.WithForegroundColor(ConsoleColor.Yellow, (o) => o.Write(stackFrame.MethodName));

                    output.Write('(');

                    for (int i = 0; i < stackFrame.Parameters.Count; ++i)
                    {
                        StackFrameParameter parameter = stackFrame.Parameters[i];

                        // "IConsole"
                        output.WithForegroundColor(ConsoleColor.Blue, (o) => o.Write(parameter.Type));

                        if (!string.IsNullOrWhiteSpace(parameter.Name))
                        {
                            output.Write(' ');

                            // "console"
                            output.WithForegroundColor(ConsoleColor.White, (o) => o.Write(parameter.Name));
                        }

                        // Separator
                        if (stackFrame.Parameters.Count > 1 && i < stackFrame.Parameters.Count - 1)
                        {
                            output.Write(", ");
                        }
                    }

                    output.Write(") ");

                    // Location
                    if (!string.IsNullOrWhiteSpace(stackFrame.FilePath))
                    {
                        output.WithForegroundColor(ConsoleColor.Magenta, (o) => o.Write("in"));
                        output.WriteLine();
                        output.Write(indentationShared);
                        output.Write(indentationLocal);
                        output.Write(indentationLocal);

                        // "C:\Projects\Typin\Typin.Demo\Commands\"
                        var stackFrameDirectoryPath = Path.GetDirectoryName(stackFrame.FilePath);
                        output.WithForegroundColor(ConsoleColor.DarkGray, (o) =>
                        {
                            o.Write(stackFrameDirectoryPath);
                            o.Write(Path.DirectorySeparatorChar);
                        });

                        // "BookAddCommand.cs"
                        string stackFrameFileName = Path.GetFileName(stackFrame.FilePath) ?? string.Empty;
                        output.WithForegroundColor(ConsoleColor.Cyan, (o) => o.Write(stackFrameFileName));

                        if (!string.IsNullOrWhiteSpace(stackFrame.LineNumber))
                        {
                            output.Write(':');

                            // "35"
                            output.WithForegroundColor(ConsoleColor.Magenta, (o) => o.Write(stackFrame.LineNumber));
                        }
                    }

                    output.WriteLine();
                }
            }
            // If any point of parsing has failed - print the stack trace without any formatting
            catch
            {
                output.WriteLine(exception.StackTrace);
            }
        }
예제 #6
0
 private static void WriteBorder(this StandardStreamWriter stream, int totalWidth, char ch = '=')
 {
     stream.WithForegroundColor(ConsoleColor.Magenta, (o) => o.WriteLine(new string(ch, totalWidth)));
 }