From 7c88a215439ea7ff69bdbdc28f0604d94976fde9 Mon Sep 17 00:00:00 2001 From: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com> Date: Tue, 9 Nov 2021 23:15:56 +0200 Subject: [PATCH] Convert several types to records --- .../Utils/Pollyfills.cs | 9 -- DiscordChatExporter.Cli/Utils/Pollyfills.cs | 9 -- DiscordChatExporter.Core/Discord/AuthToken.cs | 18 +--- .../Discord/Data/Attachment.cs | 42 ++------ .../Discord/Data/Channel.cs | 54 +++------- .../Discord/Data/ChannelCategory.cs | 24 +---- .../Discord/Data/Common/FileSize.cs | 8 +- .../Data/Common/IdBasedEqualityComparer.cs | 9 +- .../Discord/Data/Embeds/Embed.cs | 71 ++++-------- .../Discord/Data/Embeds/EmbedAuthor.cs | 29 +---- .../Discord/Data/Embeds/EmbedField.cs | 25 +---- .../Discord/Data/Embeds/EmbedFooter.cs | 25 +---- .../Discord/Data/Embeds/EmbedImage.cs | 25 +---- .../Data/Embeds/PlainImageEmbedProjection.cs | 15 +-- .../Embeds/SpotifyTrackEmbedProjection.cs | 14 +-- .../Embeds/YouTubeVideoEmbedProjection.cs | 14 +-- .../Discord/Data/Emoji.cs | 32 ++---- .../Discord/Data/Guild.cs | 24 +---- .../Discord/Data/Member.cs | 33 ++---- .../Discord/Data/Message.cs | 90 ++++------------ .../Discord/Data/MessageReference.cs | 22 +--- .../Discord/Data/Reaction.cs | 21 +--- DiscordChatExporter.Core/Discord/Data/Role.cs | 31 +----- DiscordChatExporter.Core/Discord/Data/User.cs | 37 ++----- DiscordChatExporter.Core/Discord/Snowflake.cs | 37 ++----- .../Exporting/ExportRequest.cs | 101 ++++++------------ .../Markdown/EmojiNode.cs | 26 ++--- .../Markdown/FormattingNode.cs | 25 +---- .../Markdown/InlineCodeBlockNode.cs | 17 +-- DiscordChatExporter.Core/Markdown/LinkNode.cs | 28 +---- .../Markdown/MarkdownNode.cs | 4 +- .../Markdown/MentionNode.cs | 20 +--- .../Markdown/MultiLineCodeBlockNode.cs | 20 +--- .../Markdown/Parsing/StringPart.cs | 15 +-- DiscordChatExporter.Core/Markdown/TextNode.cs | 17 +-- .../Markdown/UnixTimestampNode.cs | 11 +- DiscordChatExporter.Core/Utils/Polyfills.cs | 9 -- .../Services/SettingsService.cs | 1 - 38 files changed, 184 insertions(+), 828 deletions(-) delete mode 100644 DiscordChatExporter.Cli.Tests/Utils/Pollyfills.cs delete mode 100644 DiscordChatExporter.Cli/Utils/Pollyfills.cs delete mode 100644 DiscordChatExporter.Core/Utils/Polyfills.cs diff --git a/DiscordChatExporter.Cli.Tests/Utils/Pollyfills.cs b/DiscordChatExporter.Cli.Tests/Utils/Pollyfills.cs deleted file mode 100644 index 2e592b8..0000000 --- a/DiscordChatExporter.Cli.Tests/Utils/Pollyfills.cs +++ /dev/null @@ -1,9 +0,0 @@ -// ReSharper disable CheckNamespace -// TODO: remove after moving to .NET 5 - -namespace System.Runtime.CompilerServices -{ - internal static class IsExternalInit - { - } -} \ No newline at end of file diff --git a/DiscordChatExporter.Cli/Utils/Pollyfills.cs b/DiscordChatExporter.Cli/Utils/Pollyfills.cs deleted file mode 100644 index 2e592b8..0000000 --- a/DiscordChatExporter.Cli/Utils/Pollyfills.cs +++ /dev/null @@ -1,9 +0,0 @@ -// ReSharper disable CheckNamespace -// TODO: remove after moving to .NET 5 - -namespace System.Runtime.CompilerServices -{ - internal static class IsExternalInit - { - } -} \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/AuthToken.cs b/DiscordChatExporter.Core/Discord/AuthToken.cs index 332b01e..eea45db 100644 --- a/DiscordChatExporter.Core/Discord/AuthToken.cs +++ b/DiscordChatExporter.Core/Discord/AuthToken.cs @@ -1,27 +1,13 @@ -using System.Diagnostics.CodeAnalysis; -using System.Net.Http.Headers; +using System.Net.Http.Headers; namespace DiscordChatExporter.Core.Discord { - public class AuthToken + public record AuthToken(AuthTokenKind Kind, string Value) { - public AuthTokenKind Kind { get; } - - public string Value { get; } - - public AuthToken(AuthTokenKind kind, string value) - { - Kind = kind; - Value = value; - } - public AuthenticationHeaderValue GetAuthenticationHeader() => Kind switch { AuthTokenKind.Bot => new AuthenticationHeaderValue("Bot", Value), _ => new AuthenticationHeaderValue(Value) }; - - [ExcludeFromCodeCoverage] - public override string ToString() => Value; } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Attachment.cs b/DiscordChatExporter.Core/Discord/Data/Attachment.cs index 2b52cc6..9d13896 100644 --- a/DiscordChatExporter.Core/Discord/Data/Attachment.cs +++ b/DiscordChatExporter.Core/Discord/Data/Attachment.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text.Json; using DiscordChatExporter.Core.Discord.Data.Common; @@ -10,20 +9,16 @@ using JsonExtensions.Reading; namespace DiscordChatExporter.Core.Discord.Data { // https://discord.com/developers/docs/resources/channel#attachment-object - public partial class Attachment : IHasId + public partial record Attachment( + Snowflake Id, + string Url, + string FileName, + int? Width, + int? Height, + FileSize FileSize) : IHasId { - public Snowflake Id { get; } - - public string Url { get; } - - public string FileName { get; } - public string FileExtension => Path.GetExtension(FileName); - public int? Width { get; } - - public int? Height { get; } - public bool IsImage => FileFormat.IsImage(FileExtension); public bool IsVideo => FileFormat.IsVideo(FileExtension); @@ -31,30 +26,9 @@ namespace DiscordChatExporter.Core.Discord.Data public bool IsAudio => FileFormat.IsAudio(FileExtension); public bool IsSpoiler => FileName.StartsWith("SPOILER_", StringComparison.Ordinal); - - public FileSize FileSize { get; } - - public Attachment( - Snowflake id, - string url, - string fileName, - int? width, - int? height, - FileSize fileSize) - { - Id = id; - Url = url; - FileName = fileName; - Width = width; - Height = height; - FileSize = fileSize; - } - - [ExcludeFromCodeCoverage] - public override string ToString() => FileName; } - public partial class Attachment + public partial record Attachment { public static Attachment Parse(JsonElement json) { diff --git a/DiscordChatExporter.Core/Discord/Data/Channel.cs b/DiscordChatExporter.Core/Discord/Data/Channel.cs index a6288c3..aee392e 100644 --- a/DiscordChatExporter.Core/Discord/Data/Channel.cs +++ b/DiscordChatExporter.Core/Discord/Data/Channel.cs @@ -1,5 +1,4 @@ -using System.Diagnostics.CodeAnalysis; -using System.Linq; +using System.Linq; using System.Text.Json; using DiscordChatExporter.Core.Discord.Data.Common; using DiscordChatExporter.Core.Utils.Extensions; @@ -9,12 +8,15 @@ using Tyrrrz.Extensions; namespace DiscordChatExporter.Core.Discord.Data { // https://discord.com/developers/docs/resources/channel#channel-object - public partial class Channel : IHasId + public partial record Channel( + Snowflake Id, + ChannelKind Kind, + Snowflake GuildId, + ChannelCategory Category, + string Name, + int? Position, + string? Topic) : IHasId { - public Snowflake Id { get; } - - public ChannelKind Kind { get; } - public bool IsTextChannel => Kind is ChannelKind.GuildTextChat or ChannelKind.DirectTextChat or @@ -23,40 +25,9 @@ namespace DiscordChatExporter.Core.Discord.Data ChannelKind.GuildStore; public bool IsVoiceChannel => !IsTextChannel; - - public Snowflake GuildId { get; } - - public ChannelCategory Category { get; } - - public string Name { get; } - - public int? Position { get; } - - public string? Topic { get; } - - public Channel( - Snowflake id, - ChannelKind kind, - Snowflake guildId, - ChannelCategory category, - string name, - int? position, - string? topic) - { - Id = id; - Kind = kind; - GuildId = guildId; - Category = category; - Name = name; - Position = position; - Topic = topic; - } - - [ExcludeFromCodeCoverage] - public override string ToString() => Name; } - public partial class Channel + public partial record Channel { private static ChannelCategory GetFallbackCategory(ChannelKind channelKind) => new( Snowflake.Zero, @@ -77,13 +48,14 @@ namespace DiscordChatExporter.Core.Discord.Data var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); var guildId = json.GetPropertyOrNull("guild_id")?.GetNonWhiteSpaceString().Pipe(Snowflake.Parse); var topic = json.GetPropertyOrNull("topic")?.GetStringOrNull(); - var kind = (ChannelKind) json.GetProperty("type").GetInt32(); + var kind = (ChannelKind)json.GetProperty("type").GetInt32(); var name = // Guild channel json.GetPropertyOrNull("name")?.GetStringOrNull() ?? // DM channel - json.GetPropertyOrNull("recipients")?.EnumerateArray().Select(User.Parse).Select(u => u.Name).JoinToString(", ") ?? + json.GetPropertyOrNull("recipients")?.EnumerateArray().Select(User.Parse).Select(u => u.Name) + .JoinToString(", ") ?? // Fallback id.ToString(); diff --git a/DiscordChatExporter.Core/Discord/Data/ChannelCategory.cs b/DiscordChatExporter.Core/Discord/Data/ChannelCategory.cs index df1b08a..d576f80 100644 --- a/DiscordChatExporter.Core/Discord/Data/ChannelCategory.cs +++ b/DiscordChatExporter.Core/Discord/Data/ChannelCategory.cs @@ -1,31 +1,11 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json; +using System.Text.Json; using DiscordChatExporter.Core.Discord.Data.Common; using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Reading; namespace DiscordChatExporter.Core.Discord.Data { - public partial class ChannelCategory : IHasId - { - public Snowflake Id { get; } - - public string Name { get; } - - public int? Position { get; } - - public ChannelCategory(Snowflake id, string name, int? position) - { - Id = id; - Name = name; - Position = position; - } - - [ExcludeFromCodeCoverage] - public override string ToString() => Name; - } - - public partial class ChannelCategory + public record ChannelCategory(Snowflake Id, string Name, int? Position) : IHasId { public static ChannelCategory Unknown { get; } = new(Snowflake.Zero, "", 0); diff --git a/DiscordChatExporter.Core/Discord/Data/Common/FileSize.cs b/DiscordChatExporter.Core/Discord/Data/Common/FileSize.cs index efac8f8..5cb1362 100644 --- a/DiscordChatExporter.Core/Discord/Data/Common/FileSize.cs +++ b/DiscordChatExporter.Core/Discord/Data/Common/FileSize.cs @@ -4,16 +4,12 @@ using System.Diagnostics.CodeAnalysis; namespace DiscordChatExporter.Core.Discord.Data.Common { // Loosely based on https://github.com/omar/ByteSize (MIT license) - public readonly partial struct FileSize + public readonly partial record struct FileSize(long TotalBytes) { - public long TotalBytes { get; } - public double TotalKiloBytes => TotalBytes / 1024.0; public double TotalMegaBytes => TotalKiloBytes / 1024.0; public double TotalGigaBytes => TotalMegaBytes / 1024.0; - public FileSize(long bytes) => TotalBytes = bytes; - private double GetLargestWholeNumberValue() { if (Math.Abs(TotalGigaBytes) >= 1) @@ -46,7 +42,7 @@ namespace DiscordChatExporter.Core.Discord.Data.Common public override string ToString() => $"{GetLargestWholeNumberValue():0.##} {GetLargestWholeNumberSymbol()}"; } - public partial struct FileSize + public partial record struct FileSize { public static FileSize FromBytes(long bytes) => new(bytes); } diff --git a/DiscordChatExporter.Core/Discord/Data/Common/IdBasedEqualityComparer.cs b/DiscordChatExporter.Core/Discord/Data/Common/IdBasedEqualityComparer.cs index d897baa..04e63da 100644 --- a/DiscordChatExporter.Core/Discord/Data/Common/IdBasedEqualityComparer.cs +++ b/DiscordChatExporter.Core/Discord/Data/Common/IdBasedEqualityComparer.cs @@ -2,15 +2,12 @@ namespace DiscordChatExporter.Core.Discord.Data.Common { - public partial class IdBasedEqualityComparer : IEqualityComparer + public class IdBasedEqualityComparer : IEqualityComparer { + public static IdBasedEqualityComparer Instance { get; } = new(); + public bool Equals(IHasId? x, IHasId? y) => x?.Id == y?.Id; public int GetHashCode(IHasId obj) => obj.Id.GetHashCode(); } - - public partial class IdBasedEqualityComparer - { - public static IdBasedEqualityComparer Instance { get; } = new(); - } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Embeds/Embed.cs b/DiscordChatExporter.Core/Discord/Data/Embeds/Embed.cs index 38189cb..dea5c5d 100644 --- a/DiscordChatExporter.Core/Discord/Data/Embeds/Embed.cs +++ b/DiscordChatExporter.Core/Discord/Data/Embeds/Embed.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Linq; using System.Text.Json; @@ -10,63 +9,29 @@ using JsonExtensions.Reading; namespace DiscordChatExporter.Core.Discord.Data.Embeds { // https://discord.com/developers/docs/resources/channel#embed-object - public partial class Embed + public partial record Embed( + string? Title, + string? Url, + DateTimeOffset? Timestamp, + Color? Color, + EmbedAuthor? Author, + string? Description, + IReadOnlyList Fields, + EmbedImage? Thumbnail, + EmbedImage? Image, + EmbedFooter? Footer) { - public string? Title { get; } + public PlainImageEmbedProjection? TryGetPlainImage() => + PlainImageEmbedProjection.TryResolve(this); - public string? Url { get; } + public SpotifyTrackEmbedProjection? TryGetSpotifyTrack() => + SpotifyTrackEmbedProjection.TryResolve(this); - public DateTimeOffset? Timestamp { get; } - - public Color? Color { get; } - - public EmbedAuthor? Author { get; } - - public string? Description { get; } - - public IReadOnlyList Fields { get; } - - public EmbedImage? Thumbnail { get; } - - public EmbedImage? Image { get; } - - public EmbedFooter? Footer { get; } - - public Embed( - string? title, - string? url, - DateTimeOffset? timestamp, - Color? color, - EmbedAuthor? author, - string? description, - IReadOnlyList fields, - EmbedImage? thumbnail, - EmbedImage? image, - EmbedFooter? footer) - { - Title = title; - Url = url; - Timestamp = timestamp; - Color = color; - Author = author; - Description = description; - Fields = fields; - Thumbnail = thumbnail; - Image = image; - Footer = footer; - } - - public PlainImageEmbedProjection? TryGetPlainImage() => PlainImageEmbedProjection.TryResolve(this); - - public SpotifyTrackEmbedProjection? TryGetSpotifyTrack() => SpotifyTrackEmbedProjection.TryResolve(this); - - public YouTubeVideoEmbedProjection? TryGetYouTubeVideo() => YouTubeVideoEmbedProjection.TryResolve(this); - - [ExcludeFromCodeCoverage] - public override string ToString() => Title ?? ""; + public YouTubeVideoEmbedProjection? TryGetYouTubeVideo() => + YouTubeVideoEmbedProjection.TryResolve(this); } - public partial class Embed + public partial record Embed { public static Embed Parse(JsonElement json) { diff --git a/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedAuthor.cs b/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedAuthor.cs index 75f192c..4526c09 100644 --- a/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedAuthor.cs +++ b/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedAuthor.cs @@ -1,33 +1,14 @@ -using System.Diagnostics.CodeAnalysis; using System.Text.Json; using JsonExtensions.Reading; namespace DiscordChatExporter.Core.Discord.Data.Embeds { // https://discord.com/developers/docs/resources/channel#embed-object-embed-author-structure - public partial class EmbedAuthor - { - public string? Name { get; } - - public string? Url { get; } - - public string? IconUrl { get; } - - public string? IconProxyUrl { get; } - - public EmbedAuthor(string? name, string? url, string? iconUrl, string? iconProxyUrl) - { - Name = name; - Url = url; - IconUrl = iconUrl; - IconProxyUrl = iconProxyUrl; - } - - [ExcludeFromCodeCoverage] - public override string ToString() => Name ?? ""; - } - - public partial class EmbedAuthor + public record EmbedAuthor( + string? Name, + string? Url, + string? IconUrl, + string? IconProxyUrl) { public static EmbedAuthor Parse(JsonElement json) { diff --git a/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedField.cs b/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedField.cs index acfe240..5e632de 100644 --- a/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedField.cs +++ b/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedField.cs @@ -1,4 +1,3 @@ -using System.Diagnostics.CodeAnalysis; using System.Text.Json; using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Reading; @@ -6,26 +5,10 @@ using JsonExtensions.Reading; namespace DiscordChatExporter.Core.Discord.Data.Embeds { // https://discord.com/developers/docs/resources/channel#embed-object-embed-field-structure - public partial class EmbedField - { - public string Name { get; } - - public string Value { get; } - - public bool IsInline { get; } - - public EmbedField(string name, string value, bool isInline) - { - Name = name; - Value = value; - IsInline = isInline; - } - - [ExcludeFromCodeCoverage] - public override string ToString() => $"{Name} | {Value}"; - } - - public partial class EmbedField + public record EmbedField( + string Name, + string Value, + bool IsInline) { public static EmbedField Parse(JsonElement json) { diff --git a/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedFooter.cs b/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedFooter.cs index 5b2343d..b5763ec 100644 --- a/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedFooter.cs +++ b/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedFooter.cs @@ -1,4 +1,3 @@ -using System.Diagnostics.CodeAnalysis; using System.Text.Json; using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Reading; @@ -6,26 +5,10 @@ using JsonExtensions.Reading; namespace DiscordChatExporter.Core.Discord.Data.Embeds { // https://discord.com/developers/docs/resources/channel#embed-object-embed-footer-structure - public partial class EmbedFooter - { - public string Text { get; } - - public string? IconUrl { get; } - - public string? IconProxyUrl { get; } - - public EmbedFooter(string text, string? iconUrl, string? iconProxyUrl) - { - Text = text; - IconUrl = iconUrl; - IconProxyUrl = iconProxyUrl; - } - - [ExcludeFromCodeCoverage] - public override string ToString() => Text; - } - - public partial class EmbedFooter + public record EmbedFooter( + string Text, + string? IconUrl, + string? IconProxyUrl) { public static EmbedFooter Parse(JsonElement json) { diff --git a/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedImage.cs b/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedImage.cs index b1ebcff..c2fee1e 100644 --- a/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedImage.cs +++ b/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedImage.cs @@ -4,26 +4,11 @@ using JsonExtensions.Reading; namespace DiscordChatExporter.Core.Discord.Data.Embeds { // https://discord.com/developers/docs/resources/channel#embed-object-embed-image-structure - public partial class EmbedImage - { - public string? Url { get; } - - public string? ProxyUrl { get; } - - public int? Width { get; } - - public int? Height { get; } - - public EmbedImage(string? url, string? proxyUrl, int? width, int? height) - { - Url = url; - ProxyUrl = proxyUrl; - Height = height; - Width = width; - } - } - - public partial class EmbedImage + public record EmbedImage( + string? Url, + string? ProxyUrl, + int? Width, + int? Height) { public static EmbedImage Parse(JsonElement json) { diff --git a/DiscordChatExporter.Core/Discord/Data/Embeds/PlainImageEmbedProjection.cs b/DiscordChatExporter.Core/Discord/Data/Embeds/PlainImageEmbedProjection.cs index b520eac..04bfb0b 100644 --- a/DiscordChatExporter.Core/Discord/Data/Embeds/PlainImageEmbedProjection.cs +++ b/DiscordChatExporter.Core/Discord/Data/Embeds/PlainImageEmbedProjection.cs @@ -1,22 +1,11 @@ -using System.Diagnostics.CodeAnalysis; -using System.IO; +using System.IO; using System.Linq; using System.Text.RegularExpressions; using DiscordChatExporter.Core.Utils; namespace DiscordChatExporter.Core.Discord.Data.Embeds { - public partial class PlainImageEmbedProjection - { - public string Url { get; } - - public PlainImageEmbedProjection(string url) => Url = url; - - [ExcludeFromCodeCoverage] - public override string ToString() => Url; - } - - public partial class PlainImageEmbedProjection + public record PlainImageEmbedProjection(string Url) { public static PlainImageEmbedProjection? TryResolve(Embed embed) { diff --git a/DiscordChatExporter.Core/Discord/Data/Embeds/SpotifyTrackEmbedProjection.cs b/DiscordChatExporter.Core/Discord/Data/Embeds/SpotifyTrackEmbedProjection.cs index ca77d85..0bbe08d 100644 --- a/DiscordChatExporter.Core/Discord/Data/Embeds/SpotifyTrackEmbedProjection.cs +++ b/DiscordChatExporter.Core/Discord/Data/Embeds/SpotifyTrackEmbedProjection.cs @@ -1,21 +1,13 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.RegularExpressions; +using System.Text.RegularExpressions; namespace DiscordChatExporter.Core.Discord.Data.Embeds { - public partial class SpotifyTrackEmbedProjection + public partial record SpotifyTrackEmbedProjection(string TrackId) { - public string TrackId { get; } - public string Url => $"https://open.spotify.com/embed/track/{TrackId}"; - - public SpotifyTrackEmbedProjection(string trackId) => TrackId = trackId; - - [ExcludeFromCodeCoverage] - public override string ToString() => Url; } - public partial class SpotifyTrackEmbedProjection + public partial record SpotifyTrackEmbedProjection { private static string? TryParseTrackId(string embedUrl) { diff --git a/DiscordChatExporter.Core/Discord/Data/Embeds/YouTubeVideoEmbedProjection.cs b/DiscordChatExporter.Core/Discord/Data/Embeds/YouTubeVideoEmbedProjection.cs index bb48448..1f41862 100644 --- a/DiscordChatExporter.Core/Discord/Data/Embeds/YouTubeVideoEmbedProjection.cs +++ b/DiscordChatExporter.Core/Discord/Data/Embeds/YouTubeVideoEmbedProjection.cs @@ -1,21 +1,13 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.RegularExpressions; +using System.Text.RegularExpressions; namespace DiscordChatExporter.Core.Discord.Data.Embeds { - public partial class YouTubeVideoEmbedProjection + public partial record YouTubeVideoEmbedProjection(string VideoId) { - public string VideoId { get; } - public string Url => $"https://www.youtube.com/embed/{VideoId}"; - - public YouTubeVideoEmbedProjection(string videoId) => VideoId = videoId; - - [ExcludeFromCodeCoverage] - public override string ToString() => Url; } - public partial class YouTubeVideoEmbedProjection + public partial record YouTubeVideoEmbedProjection { // Adapted from YoutubeExplode // https://github.com/Tyrrrz/YoutubeExplode/blob/5be164be20019783913f76fcc98f18c65aebe9f0/YoutubeExplode/Videos/VideoId.cs#L34-L64 diff --git a/DiscordChatExporter.Core/Discord/Data/Emoji.cs b/DiscordChatExporter.Core/Discord/Data/Emoji.cs index 15eaf4f..ca1253a 100644 --- a/DiscordChatExporter.Core/Discord/Data/Emoji.cs +++ b/DiscordChatExporter.Core/Discord/Data/Emoji.cs @@ -1,5 +1,4 @@ -using System.Diagnostics.CodeAnalysis; -using System.Linq; +using System.Linq; using System.Text.Json; using DiscordChatExporter.Core.Utils; using DiscordChatExporter.Core.Utils.Extensions; @@ -9,36 +8,21 @@ using Tyrrrz.Extensions; namespace DiscordChatExporter.Core.Discord.Data { // https://discord.com/developers/docs/resources/emoji#emoji-object - public partial class Emoji - { + public partial record Emoji( // Only present on custom emoji - public string? Id { get; } - + string? Id, // Name of custom emoji (e.g. LUL) or actual representation of standard emoji (e.g. 🙂) - public string Name { get; } - + string Name, + bool IsAnimated, + string ImageUrl) + { // Name of custom emoji (e.g. LUL) or name of standard emoji (e.g. slight_smile) public string Code => !string.IsNullOrWhiteSpace(Id) ? Name : EmojiIndex.TryGetCode(Name) ?? Name; - - public bool IsAnimated { get; } - - public string ImageUrl { get; } - - public Emoji(string? id, string name, bool isAnimated, string imageUrl) - { - Id = id; - Name = name; - IsAnimated = isAnimated; - ImageUrl = imageUrl; - } - - [ExcludeFromCodeCoverage] - public override string ToString() => Name; } - public partial class Emoji + public partial record Emoji { private static string GetTwemojiName(string name) => name .GetRunes() diff --git a/DiscordChatExporter.Core/Discord/Data/Guild.cs b/DiscordChatExporter.Core/Discord/Data/Guild.cs index 840e8f3..4cd833c 100644 --- a/DiscordChatExporter.Core/Discord/Data/Guild.cs +++ b/DiscordChatExporter.Core/Discord/Data/Guild.cs @@ -1,5 +1,4 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json; +using System.Text.Json; using DiscordChatExporter.Core.Discord.Data.Common; using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Reading; @@ -7,26 +6,7 @@ using JsonExtensions.Reading; namespace DiscordChatExporter.Core.Discord.Data { // https://discord.com/developers/docs/resources/guild#guild-object - public partial class Guild : IHasId - { - public Snowflake Id { get; } - - public string Name { get; } - - public string IconUrl { get; } - - public Guild(Snowflake id, string name, string iconUrl) - { - Id = id; - Name = name; - IconUrl = iconUrl; - } - - [ExcludeFromCodeCoverage] - public override string ToString() => Name; - } - - public partial class Guild + public record Guild(Snowflake Id, string Name, string IconUrl) : IHasId { public static Guild DirectMessages { get; } = new( Snowflake.Zero, diff --git a/DiscordChatExporter.Core/Discord/Data/Member.cs b/DiscordChatExporter.Core/Discord/Data/Member.cs index 9711d62..cdae4c1 100644 --- a/DiscordChatExporter.Core/Discord/Data/Member.cs +++ b/DiscordChatExporter.Core/Discord/Data/Member.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text.Json; using DiscordChatExporter.Core.Discord.Data.Common; @@ -10,28 +9,15 @@ using JsonExtensions.Reading; namespace DiscordChatExporter.Core.Discord.Data { // https://discord.com/developers/docs/resources/guild#guild-member-object - public partial class Member : IHasId + public partial record Member( + User User, + string Nick, + IReadOnlyList RoleIds) : IHasId { public Snowflake Id => User.Id; - - public User User { get; } - - public string Nick { get; } - - public IReadOnlyList RoleIds { get; } - - public Member(User user, string nick, IReadOnlyList roleIds) - { - User = user; - Nick = nick; - RoleIds = roleIds; - } - - [ExcludeFromCodeCoverage] - public override string ToString() => Nick; } - public partial class Member + public partial record Member { public static Member CreateForUser(User user) => new( user, @@ -44,9 +30,12 @@ namespace DiscordChatExporter.Core.Discord.Data var user = json.GetProperty("user").Pipe(User.Parse); var nick = json.GetPropertyOrNull("nick")?.GetStringOrNull(); - var roleIds = - json.GetPropertyOrNull("roles")?.EnumerateArray().Select(j => j.GetNonWhiteSpaceString()).Select(Snowflake.Parse).ToArray() ?? - Array.Empty(); + var roleIds = json + .GetPropertyOrNull("roles")? + .EnumerateArray() + .Select(j => j.GetNonWhiteSpaceString()) + .Select(Snowflake.Parse) + .ToArray() ?? Array.Empty(); return new Member( user, diff --git a/DiscordChatExporter.Core/Discord/Data/Message.cs b/DiscordChatExporter.Core/Discord/Data/Message.cs index f03ac3a..e888eea 100644 --- a/DiscordChatExporter.Core/Discord/Data/Message.cs +++ b/DiscordChatExporter.Core/Discord/Data/Message.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text.Json; using DiscordChatExporter.Core.Discord.Data.Common; @@ -11,73 +10,21 @@ using JsonExtensions.Reading; namespace DiscordChatExporter.Core.Discord.Data { // https://discord.com/developers/docs/resources/channel#message-object - public partial class Message : IHasId - { - public Snowflake Id { get; } - - public MessageKind Kind { get; } - - public User Author { get; } - - public DateTimeOffset Timestamp { get; } - - public DateTimeOffset? EditedTimestamp { get; } - - public DateTimeOffset? CallEndedTimestamp { get; } - - public bool IsPinned { get; } - - public string Content { get; } - - public IReadOnlyList Attachments { get; } - - public IReadOnlyList Embeds { get; } - - public IReadOnlyList Reactions { get; } - - public IReadOnlyList MentionedUsers { get; } - - public MessageReference? Reference { get; } - - public Message? ReferencedMessage { get; } - - public Message( - Snowflake id, - MessageKind kind, - User author, - DateTimeOffset timestamp, - DateTimeOffset? editedTimestamp, - DateTimeOffset? callEndedTimestamp, - bool isPinned, - string content, - IReadOnlyList attachments, - IReadOnlyList embeds, - IReadOnlyList reactions, - IReadOnlyList mentionedUsers, - MessageReference? messageReference, - Message? referencedMessage) - { - Id = id; - Kind = kind; - Author = author; - Timestamp = timestamp; - EditedTimestamp = editedTimestamp; - CallEndedTimestamp = callEndedTimestamp; - IsPinned = isPinned; - Content = content; - Attachments = attachments; - Embeds = embeds; - Reactions = reactions; - MentionedUsers = mentionedUsers; - Reference = messageReference; - ReferencedMessage = referencedMessage; - } - - [ExcludeFromCodeCoverage] - public override string ToString() => Content; - } - - public partial class Message + public record Message( + Snowflake Id, + MessageKind Kind, + User Author, + DateTimeOffset Timestamp, + DateTimeOffset? EditedTimestamp, + DateTimeOffset? CallEndedTimestamp, + bool IsPinned, + string Content, + IReadOnlyList Attachments, + IReadOnlyList Embeds, + IReadOnlyList Reactions, + IReadOnlyList MentionedUsers, + MessageReference? Reference, + Message? ReferencedMessage) : IHasId { public static Message Parse(JsonElement json) { @@ -85,8 +32,9 @@ namespace DiscordChatExporter.Core.Discord.Data var author = json.GetProperty("author").Pipe(User.Parse); var timestamp = json.GetProperty("timestamp").GetDateTimeOffset(); var editedTimestamp = json.GetPropertyOrNull("edited_timestamp")?.GetDateTimeOffset(); - var callEndedTimestamp = json.GetPropertyOrNull("call")?.GetPropertyOrNull("ended_timestamp")?.GetDateTimeOffset(); - var kind = (MessageKind) json.GetProperty("type").GetInt32(); + var callEndedTimestamp = json.GetPropertyOrNull("call")?.GetPropertyOrNull("ended_timestamp") + ?.GetDateTimeOffset(); + var kind = (MessageKind)json.GetProperty("type").GetInt32(); var isPinned = json.GetPropertyOrNull("pinned")?.GetBoolean() ?? false; var messageReference = json.GetPropertyOrNull("message_reference")?.Pipe(MessageReference.Parse); var referencedMessage = json.GetPropertyOrNull("referenced_message")?.Pipe(Parse); @@ -96,7 +44,7 @@ namespace DiscordChatExporter.Core.Discord.Data MessageKind.RecipientAdd => "Added a recipient.", MessageKind.RecipientRemove => "Removed a recipient.", MessageKind.Call => - $"Started a call that lasted {callEndedTimestamp?.Pipe(t => t - timestamp).Pipe(t => (int) t.TotalMinutes) ?? 0} minutes.", + $"Started a call that lasted {callEndedTimestamp?.Pipe(t => t - timestamp).Pipe(t => (int)t.TotalMinutes) ?? 0} minutes.", MessageKind.ChannelNameChange => "Changed the channel name.", MessageKind.ChannelIconChange => "Changed the channel icon.", MessageKind.ChannelPinnedMessage => "Pinned a message.", diff --git a/DiscordChatExporter.Core/Discord/Data/MessageReference.cs b/DiscordChatExporter.Core/Discord/Data/MessageReference.cs index 419070d..2fa4b25 100644 --- a/DiscordChatExporter.Core/Discord/Data/MessageReference.cs +++ b/DiscordChatExporter.Core/Discord/Data/MessageReference.cs @@ -1,4 +1,3 @@ -using System.Diagnostics.CodeAnalysis; using System.Text.Json; using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Reading; @@ -6,26 +5,7 @@ using JsonExtensions.Reading; namespace DiscordChatExporter.Core.Discord.Data { // https://discord.com/developers/docs/resources/channel#message-object-message-reference-structure - public partial class MessageReference - { - public Snowflake? MessageId { get; } - - public Snowflake? ChannelId { get; } - - public Snowflake? GuildId { get; } - - public MessageReference(Snowflake? messageId, Snowflake? channelId, Snowflake? guildId) - { - MessageId = messageId; - ChannelId = channelId; - GuildId = guildId; - } - - [ExcludeFromCodeCoverage] - public override string ToString() => MessageId?.ToString() ?? ""; - } - - public partial class MessageReference + public record MessageReference(Snowflake? MessageId, Snowflake? ChannelId, Snowflake? GuildId) { public static MessageReference Parse(JsonElement json) { diff --git a/DiscordChatExporter.Core/Discord/Data/Reaction.cs b/DiscordChatExporter.Core/Discord/Data/Reaction.cs index ba2867f..90abae9 100644 --- a/DiscordChatExporter.Core/Discord/Data/Reaction.cs +++ b/DiscordChatExporter.Core/Discord/Data/Reaction.cs @@ -1,27 +1,10 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json; +using System.Text.Json; using DiscordChatExporter.Core.Utils.Extensions; namespace DiscordChatExporter.Core.Discord.Data { // https://discord.com/developers/docs/resources/channel#reaction-object - public partial class Reaction - { - public Emoji Emoji { get; } - - public int Count { get; } - - public Reaction(Emoji emoji, int count) - { - Emoji = emoji; - Count = count; - } - - [ExcludeFromCodeCoverage] - public override string ToString() => $"{Emoji} ({Count})"; - } - - public partial class Reaction + public record Reaction(Emoji Emoji, int Count) { public static Reaction Parse(JsonElement json) { diff --git a/DiscordChatExporter.Core/Discord/Data/Role.cs b/DiscordChatExporter.Core/Discord/Data/Role.cs index 7b75554..860a339 100644 --- a/DiscordChatExporter.Core/Discord/Data/Role.cs +++ b/DiscordChatExporter.Core/Discord/Data/Role.cs @@ -1,5 +1,4 @@ -using System.Diagnostics.CodeAnalysis; -using System.Drawing; +using System.Drawing; using System.Text.Json; using DiscordChatExporter.Core.Discord.Data.Common; using DiscordChatExporter.Core.Utils.Extensions; @@ -8,33 +7,7 @@ using JsonExtensions.Reading; namespace DiscordChatExporter.Core.Discord.Data { // https://discord.com/developers/docs/topics/permissions#role-object - public partial class Role : IHasId - { - public Snowflake Id { get; } - - public string Name { get; } - - public int Position { get; } - - public Color? Color { get; } - - public Role( - Snowflake id, - string name, - int position, - Color? color) - { - Id = id; - Name = name; - Position = position; - Color = color; - } - - [ExcludeFromCodeCoverage] - public override string ToString() => Name; - } - - public partial class Role + public record Role(Snowflake Id, string Name, int Position, Color? Color) : IHasId { public static Role Parse(JsonElement json) { diff --git a/DiscordChatExporter.Core/Discord/Data/User.cs b/DiscordChatExporter.Core/Discord/Data/User.cs index 2b1fc09..7180c86 100644 --- a/DiscordChatExporter.Core/Discord/Data/User.cs +++ b/DiscordChatExporter.Core/Discord/Data/User.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics.CodeAnalysis; using System.Text.Json; using DiscordChatExporter.Core.Discord.Data.Common; using DiscordChatExporter.Core.Utils.Extensions; @@ -8,41 +7,19 @@ using JsonExtensions.Reading; namespace DiscordChatExporter.Core.Discord.Data { // https://discord.com/developers/docs/resources/user#user-object - public partial class User : IHasId + public partial record User( + Snowflake Id, + bool IsBot, + int Discriminator, + string Name, + string AvatarUrl) : IHasId { - public Snowflake Id { get; } - - public bool IsBot { get; } - - public int Discriminator { get; } - public string DiscriminatorFormatted => $"{Discriminator:0000}"; - public string Name { get; } - public string FullName => $"{Name}#{DiscriminatorFormatted}"; - - public string AvatarUrl { get; } - - public User( - Snowflake id, - bool isBot, - int discriminator, - string name, - string avatarUrl) - { - Id = id; - IsBot = isBot; - Discriminator = discriminator; - Name = name; - AvatarUrl = avatarUrl; - } - - [ExcludeFromCodeCoverage] - public override string ToString() => FullName; } - public partial class User + public partial record User { private static string GetDefaultAvatarUrl(int discriminator) => $"https://cdn.discordapp.com/embed/avatars/{discriminator % 5}.png"; diff --git a/DiscordChatExporter.Core/Discord/Snowflake.cs b/DiscordChatExporter.Core/Discord/Snowflake.cs index 527e032..f0fe943 100644 --- a/DiscordChatExporter.Core/Discord/Snowflake.cs +++ b/DiscordChatExporter.Core/Discord/Snowflake.cs @@ -5,29 +5,20 @@ using System.Text.RegularExpressions; namespace DiscordChatExporter.Core.Discord { - public readonly partial struct Snowflake + public readonly record struct Snowflake(ulong Value) { - public ulong Value { get; } - - public Snowflake(ulong value) => Value = value; - public DateTimeOffset ToDate() => DateTimeOffset.FromUnixTimeMilliseconds( - (long) ((Value >> 22) + 1420070400000UL) + (long)((Value >> 22) + 1420070400000UL) ).ToLocalTime(); [ExcludeFromCodeCoverage] public override string ToString() => Value.ToString(CultureInfo.InvariantCulture); - } - public partial struct Snowflake - { public static Snowflake Zero { get; } = new(0); - public static Snowflake FromDate(DateTimeOffset date) - { - var value = ((ulong) date.ToUnixTimeMilliseconds() - 1420070400000UL) << 22; - return new Snowflake(value); - } + public static Snowflake FromDate(DateTimeOffset date) => new( + ((ulong)date.ToUnixTimeMilliseconds() - 1420070400000UL) << 22 + ); public static Snowflake? TryParse(string? str, IFormatProvider? formatProvider = null) { @@ -35,8 +26,7 @@ namespace DiscordChatExporter.Core.Discord return null; // As number - if (Regex.IsMatch(str, @"^\d+$") && - ulong.TryParse(str, NumberStyles.Number, formatProvider, out var value)) + if (Regex.IsMatch(str, @"^\d+$") && ulong.TryParse(str, NumberStyles.Number, formatProvider, out var value)) { return new Snowflake(value); } @@ -55,19 +45,4 @@ namespace DiscordChatExporter.Core.Discord public static Snowflake Parse(string str) => Parse(str, null); } - - public partial struct Snowflake : IComparable, IEquatable - { - public int CompareTo(Snowflake other) => Value.CompareTo(other.Value); - - public bool Equals(Snowflake other) => CompareTo(other) == 0; - - public override bool Equals(object? obj) => obj is Snowflake other && Equals(other); - - public override int GetHashCode() => Value.GetHashCode(); - - public static bool operator ==(Snowflake left, Snowflake right) => left.Equals(right); - - public static bool operator !=(Snowflake left, Snowflake right) => !(left == right); - } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/ExportRequest.cs b/DiscordChatExporter.Core/Exporting/ExportRequest.cs index 6de136e..e73d461 100644 --- a/DiscordChatExporter.Core/Exporting/ExportRequest.cs +++ b/DiscordChatExporter.Core/Exporting/ExportRequest.cs @@ -10,76 +10,35 @@ using DiscordChatExporter.Core.Utils; namespace DiscordChatExporter.Core.Exporting { - public partial class ExportRequest + public partial record ExportRequest( + Guild Guild, + Channel Channel, + string OutputPath, + ExportFormat Format, + Snowflake? After, + Snowflake? Before, + PartitionLimit PartitionLimit, + MessageFilter MessageFilter, + bool ShouldDownloadMedia, + bool ShouldReuseMedia, + string DateFormat) { - public Guild Guild { get; } - - public Channel Channel { get; } - - public string OutputPath { get; } - - public string OutputBaseFilePath { get; } - - public string OutputBaseDirPath { get; } - - public string OutputMediaDirPath { get; } - - public ExportFormat Format { get; } - - public Snowflake? After { get; } - - public Snowflake? Before { get; } - - public PartitionLimit PartitionLimit { get; } - - public MessageFilter MessageFilter { get; } - - public bool ShouldDownloadMedia { get; } - - public bool ShouldReuseMedia { get; } - - public string DateFormat { get; } - - public ExportRequest( - Guild guild, - Channel channel, - string outputPath, - ExportFormat format, - Snowflake? after, - Snowflake? before, - PartitionLimit partitionLimit, - MessageFilter messageFilter, - bool shouldDownloadMedia, - bool shouldReuseMedia, - string dateFormat) - { - Guild = guild; - Channel = channel; - OutputPath = outputPath; - Format = format; - After = after; - Before = before; - PartitionLimit = partitionLimit; - MessageFilter = messageFilter; - ShouldDownloadMedia = shouldDownloadMedia; - ShouldReuseMedia = shouldReuseMedia; - DateFormat = dateFormat; - - OutputBaseFilePath = GetOutputBaseFilePath( - guild, - channel, - outputPath, - format, - after, - before - ); - - OutputBaseDirPath = Path.GetDirectoryName(OutputBaseFilePath) ?? OutputPath; - OutputMediaDirPath = $"{OutputBaseFilePath}_Files{Path.DirectorySeparatorChar}"; - } + private string? _outputBaseFilePath; + public string OutputBaseFilePath => _outputBaseFilePath ??= GetOutputBaseFilePath( + Guild, + Channel, + OutputPath, + Format, + After, + Before + ); + + public string OutputBaseDirPath => Path.GetDirectoryName(OutputBaseFilePath) ?? OutputPath; + + public string OutputMediaDirPath => $"{OutputBaseFilePath}_Files{Path.DirectorySeparatorChar}"; } - public partial class ExportRequest + public partial record ExportRequest { private static string GetOutputBaseFilePath( Guild guild, @@ -140,17 +99,17 @@ namespace DiscordChatExporter.Core.Exporting // Both 'after' and 'before' are set if (after is not null && before is not null) { - buffer.Append($"{after?.ToDate():yyyy-MM-dd} to {before?.ToDate():yyyy-MM-dd}"); + buffer.Append($"{after.Value.ToDate():yyyy-MM-dd} to {before.Value.ToDate():yyyy-MM-dd}"); } // Only 'after' is set else if (after is not null) { - buffer.Append($"after {after?.ToDate():yyyy-MM-dd}"); + buffer.Append($"after {after.Value.ToDate():yyyy-MM-dd}"); } // Only 'before' is set - else + else if (before is not null) { - buffer.Append($"before {before?.ToDate():yyyy-MM-dd}"); + buffer.Append($"before {before.Value.ToDate():yyyy-MM-dd}"); } buffer.Append(")"); diff --git a/DiscordChatExporter.Core/Markdown/EmojiNode.cs b/DiscordChatExporter.Core/Markdown/EmojiNode.cs index e863edd..4ab6d69 100644 --- a/DiscordChatExporter.Core/Markdown/EmojiNode.cs +++ b/DiscordChatExporter.Core/Markdown/EmojiNode.cs @@ -1,38 +1,24 @@ -using System.Diagnostics.CodeAnalysis; -using DiscordChatExporter.Core.Utils; +using DiscordChatExporter.Core.Utils; namespace DiscordChatExporter.Core.Markdown { - internal class EmojiNode : MarkdownNode - { + internal record EmojiNode( // Only present on custom emoji - public string? Id { get; } - + string? Id, // Name of custom emoji (e.g. LUL) or actual representation of standard emoji (e.g. 🙂) - public string Name { get; } - + string Name, + bool IsAnimated) : MarkdownNode + { // Name of custom emoji (e.g. LUL) or name of standard emoji (e.g. slight_smile) public string Code => !string.IsNullOrWhiteSpace(Id) ? Name : EmojiIndex.TryGetCode(Name) ?? Name; - public bool IsAnimated { get; } - public bool IsCustomEmoji => !string.IsNullOrWhiteSpace(Id); - public EmojiNode(string? id, string name, bool isAnimated) - { - Id = id; - Name = name; - IsAnimated = isAnimated; - } - public EmojiNode(string name) : this(null, name, false) { } - - [ExcludeFromCodeCoverage] - public override string ToString() => $" {Name}"; } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/FormattingNode.cs b/DiscordChatExporter.Core/Markdown/FormattingNode.cs index 03bb110..4c8096d 100644 --- a/DiscordChatExporter.Core/Markdown/FormattingNode.cs +++ b/DiscordChatExporter.Core/Markdown/FormattingNode.cs @@ -1,29 +1,6 @@ using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; namespace DiscordChatExporter.Core.Markdown { - internal class FormattingNode : MarkdownNode - { - public FormattingKind Kind { get; } - - public IReadOnlyList Children { get; } - - public FormattingNode(FormattingKind kind, IReadOnlyList children) - { - Kind = kind; - Children = children; - } - - [ExcludeFromCodeCoverage] - public override string ToString() - { - var childrenFormatted = Children.Count == 1 - ? Children.Single().ToString() - : "+" + Children.Count; - - return $"<{Kind}> ({childrenFormatted})"; - } - } + internal record FormattingNode(FormattingKind Kind, IReadOnlyList Children) : MarkdownNode; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/InlineCodeBlockNode.cs b/DiscordChatExporter.Core/Markdown/InlineCodeBlockNode.cs index 7050288..9c1fbcf 100644 --- a/DiscordChatExporter.Core/Markdown/InlineCodeBlockNode.cs +++ b/DiscordChatExporter.Core/Markdown/InlineCodeBlockNode.cs @@ -1,17 +1,4 @@ -using System.Diagnostics.CodeAnalysis; - -namespace DiscordChatExporter.Core.Markdown +namespace DiscordChatExporter.Core.Markdown { - internal class InlineCodeBlockNode : MarkdownNode - { - public string Code { get; } - - public InlineCodeBlockNode(string code) - { - Code = code; - } - - [ExcludeFromCodeCoverage] - public override string ToString() => $" {Code}"; - } + internal record InlineCodeBlockNode(string Code) : MarkdownNode; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/LinkNode.cs b/DiscordChatExporter.Core/Markdown/LinkNode.cs index df4aefd..71bd611 100644 --- a/DiscordChatExporter.Core/Markdown/LinkNode.cs +++ b/DiscordChatExporter.Core/Markdown/LinkNode.cs @@ -1,34 +1,14 @@ using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; namespace DiscordChatExporter.Core.Markdown { - internal class LinkNode : MarkdownNode + internal record LinkNode( + string Url, + IReadOnlyList Children) : MarkdownNode { - public string Url { get; } - - public IReadOnlyList Children { get; } - - public LinkNode(string url, IReadOnlyList children) - { - Url = url; - Children = children; - } - public LinkNode(string url) - : this(url, new[] {new TextNode(url)}) + : this(url, new[] { new TextNode(url) }) { } - - [ExcludeFromCodeCoverage] - public override string ToString() - { - var childrenFormatted = Children.Count == 1 - ? Children.Single().ToString() - : "+" + Children.Count; - - return $" ({childrenFormatted})"; - } } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/MarkdownNode.cs b/DiscordChatExporter.Core/Markdown/MarkdownNode.cs index b6ca6a2..5bf9e8a 100644 --- a/DiscordChatExporter.Core/Markdown/MarkdownNode.cs +++ b/DiscordChatExporter.Core/Markdown/MarkdownNode.cs @@ -1,6 +1,4 @@ namespace DiscordChatExporter.Core.Markdown { - internal abstract class MarkdownNode - { - } + internal abstract record MarkdownNode; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/MentionNode.cs b/DiscordChatExporter.Core/Markdown/MentionNode.cs index 424f1e7..fb317ef 100644 --- a/DiscordChatExporter.Core/Markdown/MentionNode.cs +++ b/DiscordChatExporter.Core/Markdown/MentionNode.cs @@ -1,20 +1,4 @@ -using System.Diagnostics.CodeAnalysis; - -namespace DiscordChatExporter.Core.Markdown +namespace DiscordChatExporter.Core.Markdown { - internal class MentionNode : MarkdownNode - { - public string Id { get; } - - public MentionKind Kind { get; } - - public MentionNode(string id, MentionKind kind) - { - Id = id; - Kind = kind; - } - - [ExcludeFromCodeCoverage] - public override string ToString() => $"<{Kind} mention> {Id}"; - } + internal record MentionNode(string Id, MentionKind Kind) : MarkdownNode; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/MultiLineCodeBlockNode.cs b/DiscordChatExporter.Core/Markdown/MultiLineCodeBlockNode.cs index f89bb93..1388db9 100644 --- a/DiscordChatExporter.Core/Markdown/MultiLineCodeBlockNode.cs +++ b/DiscordChatExporter.Core/Markdown/MultiLineCodeBlockNode.cs @@ -1,20 +1,4 @@ -using System.Diagnostics.CodeAnalysis; - -namespace DiscordChatExporter.Core.Markdown +namespace DiscordChatExporter.Core.Markdown { - internal class MultiLineCodeBlockNode : MarkdownNode - { - public string Language { get; } - - public string Code { get; } - - public MultiLineCodeBlockNode(string language, string code) - { - Language = language; - Code = code; - } - - [ExcludeFromCodeCoverage] - public override string ToString() => $"<{Language}> {Code}"; - } + internal record MultiLineCodeBlockNode(string Language, string Code) : MarkdownNode; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/Parsing/StringPart.cs b/DiscordChatExporter.Core/Markdown/Parsing/StringPart.cs index 487d591..889e3b1 100644 --- a/DiscordChatExporter.Core/Markdown/Parsing/StringPart.cs +++ b/DiscordChatExporter.Core/Markdown/Parsing/StringPart.cs @@ -2,23 +2,10 @@ namespace DiscordChatExporter.Core.Markdown.Parsing { - internal readonly struct StringPart + internal readonly record struct StringPart(string Target, int StartIndex, int Length) { - public string Target { get; } - - public int StartIndex { get; } - - public int Length { get; } - public int EndIndex => StartIndex + Length; - public StringPart(string target, int startIndex, int length) - { - Target = target; - StartIndex = startIndex; - Length = length; - } - public StringPart(string target) : this(target, 0, target.Length) { diff --git a/DiscordChatExporter.Core/Markdown/TextNode.cs b/DiscordChatExporter.Core/Markdown/TextNode.cs index 44caaa3..47fcdfd 100644 --- a/DiscordChatExporter.Core/Markdown/TextNode.cs +++ b/DiscordChatExporter.Core/Markdown/TextNode.cs @@ -1,17 +1,4 @@ -using System.Diagnostics.CodeAnalysis; - -namespace DiscordChatExporter.Core.Markdown +namespace DiscordChatExporter.Core.Markdown { - internal class TextNode : MarkdownNode - { - public string Text { get; } - - public TextNode(string text) - { - Text = text; - } - - [ExcludeFromCodeCoverage] - public override string ToString() => Text; - } + internal record TextNode(string Text) : MarkdownNode; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/UnixTimestampNode.cs b/DiscordChatExporter.Core/Markdown/UnixTimestampNode.cs index 29ee110..d4d7918 100644 --- a/DiscordChatExporter.Core/Markdown/UnixTimestampNode.cs +++ b/DiscordChatExporter.Core/Markdown/UnixTimestampNode.cs @@ -1,15 +1,6 @@ using System; -using System.Diagnostics.CodeAnalysis; namespace DiscordChatExporter.Core.Markdown { - internal class UnixTimestampNode : MarkdownNode - { - public DateTimeOffset Value { get; } - - public UnixTimestampNode(DateTimeOffset value) => Value = value; - - [ExcludeFromCodeCoverage] - public override string ToString() => Value.ToString(); - } + internal record UnixTimestampNode(DateTimeOffset Value) : MarkdownNode; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Utils/Polyfills.cs b/DiscordChatExporter.Core/Utils/Polyfills.cs deleted file mode 100644 index 2e592b8..0000000 --- a/DiscordChatExporter.Core/Utils/Polyfills.cs +++ /dev/null @@ -1,9 +0,0 @@ -// ReSharper disable CheckNamespace -// TODO: remove after moving to .NET 5 - -namespace System.Runtime.CompilerServices -{ - internal static class IsExternalInit - { - } -} \ No newline at end of file diff --git a/DiscordChatExporter.Gui/Services/SettingsService.cs b/DiscordChatExporter.Gui/Services/SettingsService.cs index 852020f..cec9267 100644 --- a/DiscordChatExporter.Gui/Services/SettingsService.cs +++ b/DiscordChatExporter.Gui/Services/SettingsService.cs @@ -1,6 +1,5 @@ using DiscordChatExporter.Core.Discord; using DiscordChatExporter.Core.Exporting; -using DiscordChatExporter.Core.Exporting.Partitioning; using Tyrrrz.Settings; namespace DiscordChatExporter.Gui.Services