internal static void FormatObjectAsPlainText(FormatContext context, object value, TextWriter writer) { using var swriter = Formatter.CreateWriter(); Formatter.FormatTo(value, context, swriter, PlainTextFormatter.MimeType); var text = swriter.ToString(); FormatStringAsPlainText(text, writer); }
internal static Action <T, TextWriter> CreateFormatDelegate <T>(MemberInfo[] forMembers) { var accessors = forMembers.GetMemberAccessors <T>(); if (Formatter <T> .TypeIsValueTuple || Formatter <T> .TypeIsTuple) { return(FormatValueTuple); } if (Formatter <T> .TypeIsException) { // filter out internal values from the Data dictionary, since they're intended to be surfaced in other ways var dataAccessor = accessors.SingleOrDefault(a => a.Member.Name == "Data"); if (dataAccessor != null) { var originalGetData = dataAccessor.GetValue; dataAccessor.GetValue = e => ((IDictionary)originalGetData(e)) .Cast <DictionaryEntry>() .ToDictionary(de => de.Key, de => de.Value); } // replace the default stack trace with the full stack trace when present var stackTraceAccessor = accessors.SingleOrDefault(a => a.Member.Name == "StackTrace"); if (stackTraceAccessor != null) { stackTraceAccessor.GetValue = e => { var ex = e as Exception; return(ex.StackTrace); }; } } if (typeof(T).IsEnum) { return((enumValue, writer) => { writer.Write(enumValue.ToString()); }); } return(FormatObject); void FormatObject(T target, TextWriter writer) { Formatter.SingleLinePlainTextFormatter.WriteStartObject(writer); if (!Formatter <T> .TypeIsAnonymous) { Formatter <Type> .FormatTo(typeof(T), writer); Formatter.SingleLinePlainTextFormatter.WriteEndHeader(writer); } for (var i = 0; i < accessors.Length; i++) { var accessor = accessors[i]; if (accessor.Ignore) { continue; } object value; try { value = accessor.GetValue(target); } catch (Exception exception) { value = exception; } Formatter.SingleLinePlainTextFormatter.WriteStartProperty(writer); writer.Write(accessor.Member.Name); Formatter.SingleLinePlainTextFormatter.WriteNameValueDelimiter(writer); value.FormatTo(writer); Formatter.SingleLinePlainTextFormatter.WriteEndProperty(writer); if (i < accessors.Length - 1) { Formatter.SingleLinePlainTextFormatter.WritePropertyDelimiter(writer); } } Formatter.SingleLinePlainTextFormatter.WriteEndObject(writer); } void FormatValueTuple(T target, TextWriter writer) { Formatter.SingleLinePlainTextFormatter.WriteStartTuple(writer); for (var i = 0; i < accessors.Length; i++) { try { var accessor = accessors[i]; if (accessor.Ignore) { continue; } var value = accessor.GetValue(target); value.FormatTo(writer); Formatter.SingleLinePlainTextFormatter.WriteEndProperty(writer); if (i < accessors.Length - 1) { Formatter.SingleLinePlainTextFormatter.WritePropertyDelimiter(writer); } } catch (Exception) { } } Formatter.SingleLinePlainTextFormatter.WriteEndTuple(writer); } }
private static ConcurrentDictionary <Type, ITypeFormatter> DefaultFormatters() { var singleLineFormatter = new SingleLinePlainTextFormatter(); return(new ConcurrentDictionary <Type, ITypeFormatter> { [typeof(ExpandoObject)] = new PlainTextFormatter <ExpandoObject>((expando, writer) => { singleLineFormatter.WriteStartObject(writer); var pairs = expando.ToArray(); var length = pairs.Length; for (var i = 0; i < length; i++) { var pair = pairs[i]; writer.Write(pair.Key); singleLineFormatter.WriteNameValueDelimiter(writer); pair.Value.FormatTo(writer); if (i < length - 1) { singleLineFormatter.WritePropertyDelimiter(writer); } } singleLineFormatter.WriteEndObject(writer); }), [typeof(PocketView)] = new PlainTextFormatter <PocketView>((view, writer) => view.WriteTo(writer, HtmlEncoder.Default)), [typeof(KeyValuePair <string, object>)] = new PlainTextFormatter <KeyValuePair <string, object> >((pair, writer) => { writer.Write(pair.Key); singleLineFormatter.WriteNameValueDelimiter(writer); pair.Value.FormatTo(writer); }), [typeof(ReadOnlyMemory <char>)] = new PlainTextFormatter <ReadOnlyMemory <char> >((memory, writer) => { writer.Write(memory.Span.ToString()); }), [typeof(TimeSpan)] = new PlainTextFormatter <TimeSpan>((timespan, writer) => { writer.Write(timespan.ToString()); }), [typeof(Type)] = new PlainTextFormatter <Type>((type, writer) => { var typeName = type.FullName ?? type.Name; if (typeName.Contains("`") && !type.IsAnonymous()) { writer.Write(typeName.Remove(typeName.IndexOf('`'))); writer.Write("<"); var genericArguments = type.GetGenericArguments(); for (var i = 0; i < genericArguments.Length; i++) { Formatter <Type> .FormatTo(genericArguments[i], writer); if (i < genericArguments.Length - 1) { writer.Write(","); } } writer.Write(">"); } else { writer.Write(typeName); } }), [typeof(DateTime)] = new PlainTextFormatter <DateTime>((value, writer) => writer.Write(value.ToString("u"))), [typeof(DateTimeOffset)] = new PlainTextFormatter <DateTimeOffset>((value, writer) => writer.Write(value.ToString("u"))) }); }