Skip to content

Commit 1250331

Browse files
authored
Merge pull request #18 from WB-Tooling/formatting
Refactor BadgeWidget and LogMessageWidget for improved rendering
2 parents 1d8a1e2 + 969d603 commit 1250331

30 files changed

Lines changed: 1444 additions & 1428 deletions

.editorconfig

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,20 @@
1-
[*.{cs,vb}]
1+
# Top-level .editorconfig
2+
root = true
23

3-
# IDE0130: Der Namespace entspricht stimmt nicht der Ordnerstruktur.
4-
dotnet_diagnostic.IDE0130.severity = none
4+
# Apply to all C# files
5+
[*.cs]
6+
indent_style = space
7+
indent_size = 4
8+
9+
# New line preferences
10+
end_of_line = crlf
11+
insert_final_newline = true
12+
13+
# Apply to all XML files
14+
[*.xml]
15+
indent_style = space
16+
indent_size = 2
17+
18+
# New line preferences
19+
end_of_line = crlf
20+
insert_final_newline = true

.vscode/settings.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
"cSpell.words": [
33
"renderables"
44
],
5-
"recommendedExtensions": [
6-
"ms-dotnettools.csharp",
7-
"ms-dotnettools.csdevkit"
8-
]
5+
"[csharp]": {
6+
"editor.formatOnSave": true,
7+
"editor.defaultFormatter": "ms-dotnettools.csharp"
8+
}
99
}

src/Assembly.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
using System.Runtime.CompilerServices;
2-
3-
[assembly: InternalsVisibleTo("ExtensionsTests")]
4-
[assembly: InternalsVisibleTo("SpectreConsoleLogMessageWriterTests")]
5-
[assembly: InternalsVisibleTo("WidgetTests")]
1+
using System.Runtime.CompilerServices;
2+
3+
[assembly: InternalsVisibleTo("ExtensionsTests")]
4+
[assembly: InternalsVisibleTo("SpectreConsoleLogMessageWriterTests")]
5+
[assembly: InternalsVisibleTo("WidgetTests")]
Lines changed: 100 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,100 @@
1-
using System;
2-
using System.Threading.Tasks;
3-
using Spectre.Console;
4-
using Spectre.Console.Rendering;
5-
6-
namespace WB.Logging.LogSinks.Console.Spectre;
7-
8-
/// <summary>
9-
/// Provides extension methods for the <see cref="ILogger"/> interface.
10-
/// </summary>
11-
public static class ILoggerExtensions
12-
{
13-
// ┌─────────────────────────────────────────────────────────────────────────────┐
14-
// │ Public Methods │
15-
// └─────────────────────────────────────────────────────────────────────────────┘
16-
17-
/// <summary>
18-
/// Attaches a <see cref="SpectreConsoleLogSink"/> to <paramref name="this"/> <see cref="ILogger"/>.
19-
/// </summary>
20-
/// <param name="this">The <see cref="ILogger"/> instance to attach the log sink to.</param>
21-
/// <param name="configure">An optional action to configure the <see cref="SpectreConsoleLogSink"/> after it has been created and attached.</param>
22-
/// <returns>An <see cref="IDisposable"/> that can be used to detach the log sink from the logger when it is no longer needed.</returns>
23-
public static IDisposable AttachSpectreConsole(this ILogger @this, Action<SpectreConsoleLogSink>? configure = null)
24-
{
25-
ArgumentNullException.ThrowIfNull(@this);
26-
27-
SpectreConsoleLogSink logSink = new();
28-
29-
IDisposable disposable = @this.AttachLogSink(logSink);
30-
31-
configure?.Invoke(logSink);
32-
33-
return disposable;
34-
}
35-
36-
/// <summary>
37-
/// Logs the <paramref name="widget"/> as a log message. This method allows you to log any
38-
/// Spectre.Console widget directly by passing it as an argument.
39-
/// </summary>
40-
/// <remarks>The <paramref name="widget"/> is logged with a <c>null</c> <see cref="LogLevel"/>.</remarks>
41-
/// <param name="this">The <see cref="ILogger"/> instance to log the widget to.</param>
42-
/// <param name="widget">The Spectre.Console widget to log.</param>
43-
/// <returns>The same <see cref="ILogger"/> instance to allow for method chaining.</returns>
44-
/// <seealso cref="IRenderable"/>
45-
public static ILogger Widget(this ILogger @this, IRenderable widget)
46-
{
47-
ArgumentNullException.ThrowIfNull(@this);
48-
49-
@this.Log(null, new WidgetPayload(widget));
50-
51-
return @this;
52-
}
53-
54-
/// <summary>
55-
/// Logs a horizontal rule to the console.
56-
/// </summary>
57-
/// <param name="this">The <see cref="ILogger"/> instance to log the horizontal rule to.</param>
58-
/// <param name="title">An optional title to display in the center of the horizontal rule.</param>
59-
/// <returns>The same <see cref="ILogger"/> instance to allow for method chaining.</returns>
60-
public static ILogger HorizontalRule(this ILogger @this, string? title = null)
61-
{
62-
ArgumentNullException.ThrowIfNull(@this);
63-
64-
if (title is null)
65-
{
66-
return @this.Widget(new Rule());
67-
}
68-
else
69-
{
70-
@this.Widget(new Rule(title));
71-
}
72-
73-
return @this;
74-
}
75-
76-
/// <summary>
77-
/// Starts a progress with the specified <paramref name="title"/> and <paramref name="progress"/> function.
78-
/// The progress will be automatically completed when the <paramref name="progress"/> function completes.
79-
/// </summary>
80-
/// <param name="this">The <see cref="ILogger"/> instance to start the progress on.</param>
81-
/// <param name="title">The title of the progress.</param>
82-
/// <param name="progress">The function that performs the progress.</param>
83-
/// <returns>A task that represents the asynchronous operation.</returns>
84-
public static async Task StartProgressAsync(this ILogger @this, string title, Func<ProgressContext, Task> progress)
85-
{
86-
ArgumentNullException.ThrowIfNull(@this);
87-
88-
ProgressPayload progressPayload = new()
89-
{
90-
Title = title,
91-
Progress = progress,
92-
};
93-
94-
await @this.FlushAsync().ConfigureAwait(false);
95-
96-
@this.Log(null, progressPayload);
97-
98-
await progressPayload.Completed.ConfigureAwait(false);
99-
}
100-
}
1+
using System;
2+
using System.Threading.Tasks;
3+
using Spectre.Console;
4+
using Spectre.Console.Rendering;
5+
6+
namespace WB.Logging.LogSinks.Console.Spectre;
7+
8+
/// <summary>
9+
/// Provides extension methods for the <see cref="ILogger"/> interface.
10+
/// </summary>
11+
public static class ILoggerExtensions
12+
{
13+
// ┌─────────────────────────────────────────────────────────────────────────────┐
14+
// │ Public Methods │
15+
// └─────────────────────────────────────────────────────────────────────────────┘
16+
17+
/// <summary>
18+
/// Attaches a <see cref="SpectreConsoleLogSink"/> to <paramref name="this"/> <see cref="ILogger"/>.
19+
/// </summary>
20+
/// <param name="this">The <see cref="ILogger"/> instance to attach the log sink to.</param>
21+
/// <param name="configure">An optional action to configure the <see cref="SpectreConsoleLogSink"/> after it has been created and attached.</param>
22+
/// <returns>An <see cref="IDisposable"/> that can be used to detach the log sink from the logger when it is no longer needed.</returns>
23+
public static IDisposable AttachSpectreConsole(this ILogger @this, Action<SpectreConsoleLogSink>? configure = null)
24+
{
25+
ArgumentNullException.ThrowIfNull(@this);
26+
27+
SpectreConsoleLogSink logSink = new();
28+
29+
IDisposable disposable = @this.AttachLogSink(logSink);
30+
31+
configure?.Invoke(logSink);
32+
33+
return disposable;
34+
}
35+
36+
/// <summary>
37+
/// Logs the <paramref name="widget"/> as a log message. This method allows you to log any
38+
/// Spectre.Console widget directly by passing it as an argument.
39+
/// </summary>
40+
/// <remarks>The <paramref name="widget"/> is logged with a <c>null</c> <see cref="LogLevel"/>.</remarks>
41+
/// <param name="this">The <see cref="ILogger"/> instance to log the widget to.</param>
42+
/// <param name="widget">The Spectre.Console widget to log.</param>
43+
/// <returns>The same <see cref="ILogger"/> instance to allow for method chaining.</returns>
44+
/// <seealso cref="IRenderable"/>
45+
public static ILogger Widget(this ILogger @this, IRenderable widget)
46+
{
47+
ArgumentNullException.ThrowIfNull(@this);
48+
49+
@this.Log(null, new WidgetPayload(widget));
50+
51+
return @this;
52+
}
53+
54+
/// <summary>
55+
/// Logs a horizontal rule to the console.
56+
/// </summary>
57+
/// <param name="this">The <see cref="ILogger"/> instance to log the horizontal rule to.</param>
58+
/// <param name="title">An optional title to display in the center of the horizontal rule.</param>
59+
/// <returns>The same <see cref="ILogger"/> instance to allow for method chaining.</returns>
60+
public static ILogger HorizontalRule(this ILogger @this, string? title = null)
61+
{
62+
ArgumentNullException.ThrowIfNull(@this);
63+
64+
if (title is null)
65+
{
66+
return @this.Widget(new Rule());
67+
}
68+
else
69+
{
70+
@this.Widget(new Rule(title));
71+
}
72+
73+
return @this;
74+
}
75+
76+
/// <summary>
77+
/// Starts a progress with the specified <paramref name="title"/> and <paramref name="progress"/> function.
78+
/// The progress will be automatically completed when the <paramref name="progress"/> function completes.
79+
/// </summary>
80+
/// <param name="this">The <see cref="ILogger"/> instance to start the progress on.</param>
81+
/// <param name="title">The title of the progress.</param>
82+
/// <param name="progress">The function that performs the progress.</param>
83+
/// <returns>A task that represents the asynchronous operation.</returns>
84+
public static async Task StartProgressAsync(this ILogger @this, string title, Func<ProgressContext, Task> progress)
85+
{
86+
ArgumentNullException.ThrowIfNull(@this);
87+
88+
ProgressPayload progressPayload = new()
89+
{
90+
Title = title,
91+
Progress = progress,
92+
};
93+
94+
await @this.FlushAsync().ConfigureAwait(false);
95+
96+
@this.Log(null, progressPayload);
97+
98+
await progressPayload.Completed.ConfigureAwait(false);
99+
}
100+
}

src/Extensions/ObjectExtensions.cs

Lines changed: 64 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,64 @@
1-
using System;
2-
using System.Collections.Concurrent;
3-
using System.Reflection;
4-
using System.Text.Json;
5-
using Spectre.Console;
6-
using Spectre.Console.Json;
7-
using Spectre.Console.Rendering;
8-
9-
namespace WB.Logging.LogSinks.Console.Spectre;
10-
11-
internal static class ObjectExtensions
12-
{
13-
private static readonly ConcurrentDictionary<Type, bool> ToStringOverrideCache = new();
14-
15-
internal static bool HasOverriddenToString<TObject>(this TObject @this)
16-
{
17-
if (@this is null)
18-
{
19-
return false;
20-
}
21-
22-
Type type = @this.GetType();
23-
24-
return ToStringOverrideCache.GetOrAdd(type, type =>
25-
{
26-
MethodInfo? methodInfo = type.GetMethod(nameof(ToString), Type.EmptyTypes);
27-
28-
return methodInfo?.DeclaringType != typeof(object);
29-
});
30-
}
31-
32-
internal static IRenderable ToRenderable<TObject>(this TObject @this, Style? style = null)
33-
{
34-
if (@this is null)
35-
{
36-
return new Text("null", style);
37-
}
38-
39-
if (@this is IRenderable renderable)
40-
{
41-
return renderable;
42-
}
43-
44-
if (@this is string @string)
45-
{
46-
return @string.ToMarkup(style);
47-
}
48-
49-
if (@this.HasOverriddenToString())
50-
{
51-
return new Text(@this.ToString() ?? string.Empty, style);
52-
}
53-
else
54-
{
55-
return new JsonText(@this.ToJsonString());
56-
}
57-
}
58-
59-
// ┌─────────────────────────────────────────────────────────────────────────────┐
60-
// │ Private Methods │
61-
// └─────────────────────────────────────────────────────────────────────────────┘
62-
private static string ToJsonString(this object @this)
63-
=> JsonSerializer.Serialize(@this);
64-
}
1+
using System;
2+
using System.Collections.Concurrent;
3+
using System.Reflection;
4+
using System.Text.Json;
5+
using Spectre.Console;
6+
using Spectre.Console.Json;
7+
using Spectre.Console.Rendering;
8+
9+
namespace WB.Logging.LogSinks.Console.Spectre;
10+
11+
internal static class ObjectExtensions
12+
{
13+
private static readonly ConcurrentDictionary<Type, bool> ToStringOverrideCache = new();
14+
15+
internal static bool HasOverriddenToString<TObject>(this TObject @this)
16+
{
17+
if (@this is null)
18+
{
19+
return false;
20+
}
21+
22+
Type type = @this.GetType();
23+
24+
return ToStringOverrideCache.GetOrAdd(type, type =>
25+
{
26+
MethodInfo? methodInfo = type.GetMethod(nameof(ToString), Type.EmptyTypes);
27+
28+
return methodInfo?.DeclaringType != typeof(object);
29+
});
30+
}
31+
32+
internal static IRenderable ToRenderable<TObject>(this TObject @this, Style? style = null)
33+
{
34+
if (@this is null)
35+
{
36+
return new Text("null", style);
37+
}
38+
39+
if (@this is IRenderable renderable)
40+
{
41+
return renderable;
42+
}
43+
44+
if (@this is string @string)
45+
{
46+
return @string.ToMarkup(style);
47+
}
48+
49+
if (@this.HasOverriddenToString())
50+
{
51+
return new Text(@this.ToString() ?? string.Empty, style);
52+
}
53+
else
54+
{
55+
return new JsonText(@this.ToJsonString());
56+
}
57+
}
58+
59+
// ┌─────────────────────────────────────────────────────────────────────────────┐
60+
// │ Private Methods │
61+
// └─────────────────────────────────────────────────────────────────────────────┘
62+
private static string ToJsonString(this object @this)
63+
=> JsonSerializer.Serialize(@this);
64+
}

0 commit comments

Comments
 (0)