diff --git a/code generation/OpenLibraryNET.Diagnostics/OpenLibraryNET.Diagnostics.csproj b/code generation/OpenLibraryNET.Diagnostics/OpenLibraryNET.Diagnostics.csproj index 3ce0ea5..adcc450 100644 --- a/code generation/OpenLibraryNET.Diagnostics/OpenLibraryNET.Diagnostics.csproj +++ b/code generation/OpenLibraryNET.Diagnostics/OpenLibraryNET.Diagnostics.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + net10.0 true true diff --git a/code generation/OpenLibraryNET.GeneratorAttributes/CollectionValueEqualityAttribute.cs b/code generation/OpenLibraryNET.GeneratorAttributes/CollectionValueEqualityAttribute.cs index 4a2b9c7..8c23f88 100644 --- a/code generation/OpenLibraryNET.GeneratorAttributes/CollectionValueEqualityAttribute.cs +++ b/code generation/OpenLibraryNET.GeneratorAttributes/CollectionValueEqualityAttribute.cs @@ -5,6 +5,6 @@ namespace CodeGeneration_Attributes { [AttributeUsage(AttributeTargets.Class, Inherited = false)] - public sealed class CollectionValueEqualityAttribute : Attribute + public class CollectionValueEqualityAttribute : Attribute { } } diff --git a/code generation/OpenLibraryNET.GeneratorAttributes/GenerateEqualsAttribute.cs b/code generation/OpenLibraryNET.GeneratorAttributes/GenerateEqualsAttribute.cs index f27668b..80a8885 100644 --- a/code generation/OpenLibraryNET.GeneratorAttributes/GenerateEqualsAttribute.cs +++ b/code generation/OpenLibraryNET.GeneratorAttributes/GenerateEqualsAttribute.cs @@ -5,6 +5,6 @@ namespace CodeGeneration_Attributes { [AttributeUsage(AttributeTargets.Class, Inherited = false)] - public sealed class GenerateEqualsAttribute : Attribute + public class GenerateEqualsAttribute : Attribute { } } diff --git a/code generation/OpenLibraryNET.GeneratorAttributes/GenerateGetHashCodeAttribute.cs b/code generation/OpenLibraryNET.GeneratorAttributes/GenerateGetHashCodeAttribute.cs index 3e5a905..5b0aad9 100644 --- a/code generation/OpenLibraryNET.GeneratorAttributes/GenerateGetHashCodeAttribute.cs +++ b/code generation/OpenLibraryNET.GeneratorAttributes/GenerateGetHashCodeAttribute.cs @@ -7,6 +7,6 @@ namespace CodeGeneration_Attributes { [AttributeUsage(AttributeTargets.Class, Inherited = false)] - public sealed class GenerateGetHashCodeAttribute : Attribute + public class GenerateGetHashCodeAttribute : Attribute { } } diff --git a/code generation/OpenLibraryNET.GeneratorAttributes/IgnoreEqualityAttribute.cs b/code generation/OpenLibraryNET.GeneratorAttributes/IgnoreEqualityAttribute.cs index e8b8c89..4349ee4 100644 --- a/code generation/OpenLibraryNET.GeneratorAttributes/IgnoreEqualityAttribute.cs +++ b/code generation/OpenLibraryNET.GeneratorAttributes/IgnoreEqualityAttribute.cs @@ -5,6 +5,6 @@ namespace CodeGeneration_Attributes { [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = false)] - public sealed class IgnoreEqualityAttribute : Attribute + public class IgnoreEqualityAttribute : Attribute { } } diff --git a/code generation/OpenLibraryNET.GeneratorAttributes/OpenLibraryNET.GeneratorAttributes.csproj b/code generation/OpenLibraryNET.GeneratorAttributes/OpenLibraryNET.GeneratorAttributes.csproj index c9ac0e3..597f563 100644 --- a/code generation/OpenLibraryNET.GeneratorAttributes/OpenLibraryNET.GeneratorAttributes.csproj +++ b/code generation/OpenLibraryNET.GeneratorAttributes/OpenLibraryNET.GeneratorAttributes.csproj @@ -1,6 +1,6 @@  - netstandard2.0 + net10.0 diff --git a/code generation/OpenLibraryNET.RemoveGeneratorAttributes/OpenLibraryNET.RemoveGeneratorAttributes.csproj b/code generation/OpenLibraryNET.RemoveGeneratorAttributes/OpenLibraryNET.RemoveGeneratorAttributes.csproj index 03cc9c8..dd03693 100644 --- a/code generation/OpenLibraryNET.RemoveGeneratorAttributes/OpenLibraryNET.RemoveGeneratorAttributes.csproj +++ b/code generation/OpenLibraryNET.RemoveGeneratorAttributes/OpenLibraryNET.RemoveGeneratorAttributes.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net10.0 enable enable diff --git a/code generation/OpenLibraryNET.SourceGenerators/EqualsGenerator.cs b/code generation/OpenLibraryNET.SourceGenerators/EqualsGenerator.cs index 6bf526b..706e5de 100644 --- a/code generation/OpenLibraryNET.SourceGenerators/EqualsGenerator.cs +++ b/code generation/OpenLibraryNET.SourceGenerators/EqualsGenerator.cs @@ -75,14 +75,14 @@ private string GetContents(INamedTypeSymbol symbol, ISymbol iEnumerableSymbol, I { StringBuilder sb = new StringBuilder(); - sb.Append("///\n///Determines whether the specified object is equal to the current object.\n///Compares all fields by value; IEnumerables are compared by comparing the elements pairwise.\n///\n///The object to compare with the current object.\n///true if the specified object is equal to the current object; otherwise, false.\n"); + sb.Append("///\r\n///Determines whether the specified object is equal to the current object.\r\n///Compares all fields by value; IEnumerables are compared by comparing the elements pairwise.\r\n///\r\n///The object to compare with the current object.\r\n///true if the specified object is equal to the current object; otherwise, false.\r\n"); if (symbol.TypeKind == TypeKind.Struct) { - sb.Append($"[System.CodeDom.Compiler.GeneratedCode(\"{Utility.ToolName}\", \"{Utility.ToolVersion}\")]\npublic bool Equals({symbol.Name} other)\n{{"); + sb.Append($"[System.CodeDom.Compiler.GeneratedCode(\"{Utility.ToolName}\", \"{Utility.ToolVersion}\")]\r\npublic bool Equals({symbol.Name} other)\r\n{{"); } else { - sb.Append($"[System.CodeDom.Compiler.GeneratedCode(\"{Utility.ToolName}\", \"{Utility.ToolVersion}\")]\npublic bool Equals({symbol.Name} other)\n{{"); + sb.Append($"[System.CodeDom.Compiler.GeneratedCode(\"{Utility.ToolName}\", \"{Utility.ToolVersion}\")]\r\npublic virtual bool Equals({symbol.Name} other)\r\n{{"); } List members = symbol.GetMembers().OfType().ToList(); @@ -91,11 +91,11 @@ private string GetContents(INamedTypeSymbol symbol, ISymbol iEnumerableSymbol, I { if (symbol.TypeKind == TypeKind.Struct) { - sb.Append($"\n\treturn true"); + sb.Append($"\r\n\treturn true"); } else { - sb.Append($"\n\treturn other != null"); + sb.Append($"\r\n\treturn other != null"); } } @@ -113,11 +113,11 @@ private string GetContents(INamedTypeSymbol symbol, ISymbol iEnumerableSymbol, I if (symbol.TypeKind == TypeKind.Struct) { - sb.Append($"\n\treturn"); + sb.Append($"\r\n\treturn"); } else { - sb.Append($"\n\treturn other != null &&"); + sb.Append($"\r\n\treturn other != null &&"); } } else @@ -128,15 +128,15 @@ private string GetContents(INamedTypeSymbol symbol, ISymbol iEnumerableSymbol, I if (!SymbolEqualityComparer.Default.Equals(members[i].Type, stringSymbol) && members[i].Type.AllInterfaces.Any(sym => SymbolEqualityComparer.Default.Equals(sym, iEnumerableSymbol))) { - sb.Append($"\n\t(({assoc.Name} == null && other.{assoc.Name} == null) || ({assoc.Name} != null && other.{assoc.Name} != null && {assoc.Name}.SequenceEqual(other.{assoc.Name})))"); + sb.Append($"\r\n\t(({assoc.Name} == null && other.{assoc.Name} == null) || ({assoc.Name} != null && other.{assoc.Name} != null && {assoc.Name}.SequenceEqual(other.{assoc.Name})))"); } else { - sb.Append($"\n\t{assoc.Name} == other.{assoc.Name}"); + sb.Append($"\r\n\t{assoc.Name} == other.{assoc.Name}"); } } - sb.Append(";\n}"); + sb.Append(";\r\n}"); // TODO diff --git a/code generation/OpenLibraryNET.SourceGenerators/GetHashCodeGenerator.cs b/code generation/OpenLibraryNET.SourceGenerators/GetHashCodeGenerator.cs index 0ac8fa2..c2a07b6 100644 --- a/code generation/OpenLibraryNET.SourceGenerators/GetHashCodeGenerator.cs +++ b/code generation/OpenLibraryNET.SourceGenerators/GetHashCodeGenerator.cs @@ -74,8 +74,8 @@ private string GetContents(GeneratorExecutionContext context, INamedTypeSymbol s { StringBuilder sb = new StringBuilder(); - sb.Append("///\n///Serves as the default hash function.\n///IEnumerables are hashed element-wise.\n///\n///A hash code for the current object.\n"); - sb.Append($"[System.CodeDom.Compiler.GeneratedCode(\"{Utility.ToolName}\", \"{Utility.ToolVersion}\")]\npublic override int GetHashCode()\n{{\n\tHashCode hash = new HashCode();"); + sb.Append("///\r\n///Serves as the default hash function.\r\n///IEnumerables are hashed element-wise.\r\n///\r\n///A hash code for the current object.\r\n"); + sb.Append($"[System.CodeDom.Compiler.GeneratedCode(\"{Utility.ToolName}\", \"{Utility.ToolVersion}\")]\r\npublic override int GetHashCode()\r\n{{\r\n\tHashCode hash = new HashCode();"); ISymbol iEnumerableSymbol = context.Compilation.GetSpecialType(SpecialType.System_Collections_IEnumerable); ISymbol stringSymbol = context.Compilation.GetSpecialType(SpecialType.System_String); @@ -91,15 +91,15 @@ private string GetContents(GeneratorExecutionContext context, INamedTypeSymbol s if (!SymbolEqualityComparer.Default.Equals(members[i].Type, stringSymbol) && members[i].Type.AllInterfaces.Any(sym => SymbolEqualityComparer.Default.Equals(sym, iEnumerableSymbol))) { - sb.Append($"\n\tif ({assoc.Name} != null)\n\t{{\n\t\tforeach (var element in {assoc.Name})\n\t\t{{\n\t\t\thash.Add(element);\n\t\t}}\n\t}}\n\telse\n\t{{\n\t\thash.Add({assoc.Name});\n\t}}"); + sb.Append($"\r\n\tif ({assoc.Name} != null)\r\n\t{{\r\n\t\tforeach (var element in {assoc.Name})\r\n\t\t{{\r\n\t\t\thash.Add(element);\r\n\t\t}}\r\n\t}}\r\n\telse\r\n\t{{\r\n\t\thash.Add({assoc.Name});\r\n\t}}"); } else { - sb.Append($"\n\thash.Add(this.{assoc.Name});"); + sb.Append($"\r\n\thash.Add(this.{assoc.Name});"); } } - sb.Append("\n\treturn hash.ToHashCode();\n}"); + sb.Append("\r\n\treturn hash.ToHashCode();\r\n}"); return sb.ToString(); } } \ No newline at end of file diff --git a/code generation/OpenLibraryNET.SourceGenerators/OpenLibraryNET.SourceGenerators.csproj b/code generation/OpenLibraryNET.SourceGenerators/OpenLibraryNET.SourceGenerators.csproj index 4838dc1..b03ed57 100644 --- a/code generation/OpenLibraryNET.SourceGenerators/OpenLibraryNET.SourceGenerators.csproj +++ b/code generation/OpenLibraryNET.SourceGenerators/OpenLibraryNET.SourceGenerators.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + net10.0 true true diff --git a/code generation/OpenLibraryNET.SourceGenerators/Utility.cs b/code generation/OpenLibraryNET.SourceGenerators/Utility.cs index 6c03a2d..15a9239 100644 --- a/code generation/OpenLibraryNET.SourceGenerators/Utility.cs +++ b/code generation/OpenLibraryNET.SourceGenerators/Utility.cs @@ -78,7 +78,7 @@ public static string BuildSource(INamedTypeSymbol symbol, string contents) if (symbol.ContainingNamespace != null) { - sb.AppendLine($"namespace {symbol.ContainingNamespace.ToDisplayString()}\n{{"); + sb.AppendLine($"namespace {symbol.ContainingNamespace.ToDisplayString()}\r\n{{"); indent++; } @@ -94,19 +94,19 @@ public static string BuildSource(INamedTypeSymbol symbol, string contents) foreach (var currentSymbol in containingTypes) { - sb.AppendIndented($"\n{GetDeclaration(currentSymbol)}\n{{", indent); + sb.AppendIndented($"\r\n{GetDeclaration(currentSymbol)}\r\n{{", indent); indent++; } } - sb.AppendIndented($"\n{GetDeclaration(symbol)}\n{{", indent); + sb.AppendIndented($"\r\n{GetDeclaration(symbol)}\r\n{{", indent); indent++; sb.AppendIndented(contents, indent); indent--; while (indent >= 0) { - sb.AppendIndented("\n}", indent); + sb.AppendIndented("\r\n}", indent); indent--; } @@ -115,8 +115,7 @@ public static string BuildSource(INamedTypeSymbol symbol, string contents) public static StringBuilder AppendIndented(this StringBuilder sb, string textBlock, int indentationLevel) { - char[] chars = new char[1] { '\n' }; - foreach (var line in textBlock.TrimEnd().Split(chars, StringSplitOptions.RemoveEmptyEntries)) + foreach (var line in textBlock.TrimEnd().Split(new[] { "\r\n", "\n", "\r" }, StringSplitOptions.None)) if (!string.IsNullOrWhiteSpace(line)) sb.AppendLine($"{string.Concat(Enumerable.Repeat("\t", indentationLevel))}{line}"); return sb; diff --git a/src/OLAuthor.cs b/src/OLAuthor.cs index 54966f0..02f5806 100644 --- a/src/OLAuthor.cs +++ b/src/OLAuthor.cs @@ -10,7 +10,7 @@ namespace OpenLibraryNET /// Composite storage of various data related to an author. /// [CollectionValueEquality] - public sealed partial record OLAuthor + public partial record OLAuthor { /// /// The ID of the author. diff --git a/src/OLData/OLAuthorData.cs b/src/OLData/OLAuthorData.cs index b659405..2576a2e 100644 --- a/src/OLData/OLAuthorData.cs +++ b/src/OLData/OLAuthorData.cs @@ -9,7 +9,7 @@ namespace OpenLibraryNET.Data /// Holds data about an author. /// [CollectionValueEquality] - public sealed partial record OLAuthorData : OLContainer + public partial record OLAuthorData : OLContainer { /// /// The ID of the author. diff --git a/src/OLData/OLBookViewAPI.cs b/src/OLData/OLBookViewAPI.cs index 2f76cf5..5d5a5ff 100644 --- a/src/OLData/OLBookViewAPI.cs +++ b/src/OLData/OLBookViewAPI.cs @@ -7,7 +7,7 @@ namespace OpenLibraryNET.Data /// Holds data about a book's ViewAPI. /// [CollectionValueEquality] - public sealed partial record OLBookViewAPI : OLContainer + public partial record OLBookViewAPI : OLContainer { /// /// The book's bibkey. diff --git a/src/OLData/OLBookshelvesData.cs b/src/OLData/OLBookshelvesData.cs index 49c69dc..25cc153 100644 --- a/src/OLData/OLBookshelvesData.cs +++ b/src/OLData/OLBookshelvesData.cs @@ -7,7 +7,7 @@ namespace OpenLibraryNET.Data /// Holds data about a 's bookshelves. /// [CollectionValueEquality] - public sealed partial record OLBookshelvesData : OLContainer + public partial record OLBookshelvesData : OLContainer { /// /// The amount of accounts that marked the corresponding work as "Want to read". diff --git a/src/OLData/OLEditionData.cs b/src/OLData/OLEditionData.cs index 9ca8956..b15426b 100644 --- a/src/OLData/OLEditionData.cs +++ b/src/OLData/OLEditionData.cs @@ -9,7 +9,7 @@ namespace OpenLibraryNET.Data /// Holds data about an edition. /// [CollectionValueEquality] - public sealed partial record OLEditionData : OLContainer + public partial record OLEditionData : OLContainer { /// /// The edition's ID. @@ -138,7 +138,7 @@ public IReadOnlyList Publishers /// Holds the various identifiers of an edition. /// [CollectionValueEquality] - public sealed partial record OLEditionIdentifiers : OLContainer + public partial record OLEditionIdentifiers : OLContainer { /// /// The Goodreads identifiers of the corresponding edition. diff --git a/src/OLData/OLListData.cs b/src/OLData/OLListData.cs index 42c1d0d..d314ffe 100644 --- a/src/OLData/OLListData.cs +++ b/src/OLData/OLListData.cs @@ -8,7 +8,7 @@ namespace OpenLibraryNET.Data /// Holds data about a user-created list. /// [CollectionValueEquality] - public sealed partial record OLListData : OLContainer + public partial record OLListData : OLContainer { /// /// The list's ID. diff --git a/src/OLData/OLMyBooksData.cs b/src/OLData/OLMyBooksData.cs index e14706f..f973ec8 100644 --- a/src/OLData/OLMyBooksData.cs +++ b/src/OLData/OLMyBooksData.cs @@ -8,7 +8,7 @@ namespace OpenLibraryNET.Data /// Holds data about a user's reading log. /// [CollectionValueEquality] - public sealed partial record OLMyBooksData : OLContainer + public partial record OLMyBooksData : OLContainer { /// /// Pagination data about the reading log.
@@ -34,7 +34,7 @@ public IReadOnlyList ReadingLogEntries /// Holds data about an entry in a given reading log. ///
[CollectionValueEquality] - public sealed partial record OLReadingLogEntry : OLContainer + public partial record OLReadingLogEntry : OLContainer { /// /// The corresponding . diff --git a/src/OLData/OLPartnerData.cs b/src/OLData/OLPartnerData.cs index 56b125f..3935a71 100644 --- a/src/OLData/OLPartnerData.cs +++ b/src/OLData/OLPartnerData.cs @@ -9,7 +9,7 @@ namespace OpenLibraryNET.Data /// Holds data about online-readable or borrowable books, along with corresponding and entries. /// [CollectionValueEquality] - public sealed partial record OLPartnerData : OLContainer + public partial record OLPartnerData : OLContainer { /// /// The corresponding . @@ -39,7 +39,7 @@ public IReadOnlyList Items /// Holds data about an online-readable book. /// [CollectionValueEquality] - public sealed partial record Item : OLContainer + public partial record Item : OLContainer { /// /// The type of match. Either 'exact' or 'similar'. @@ -81,7 +81,7 @@ public sealed partial record Item : OLContainer /// Holds URLs to the cover of the corresponding . /// [CollectionValueEquality] - public sealed partial record CoverURL : OLContainer + public partial record CoverURL : OLContainer { /// /// Link to the cover in small resolution. diff --git a/src/OLData/OLRatingsData.cs b/src/OLData/OLRatingsData.cs index 36adc80..8329924 100644 --- a/src/OLData/OLRatingsData.cs +++ b/src/OLData/OLRatingsData.cs @@ -7,7 +7,7 @@ namespace OpenLibraryNET.Data /// Holds data about a 's ratings. /// [CollectionValueEquality] - public sealed partial record OLRatingsData : OLContainer + public partial record OLRatingsData : OLContainer { /// /// The corresponding work's average rating. Null if there are no ratings. diff --git a/src/OLData/OLRecentChangesData.cs b/src/OLData/OLRecentChangesData.cs index 92f809c..a9c73f1 100644 --- a/src/OLData/OLRecentChangesData.cs +++ b/src/OLData/OLRecentChangesData.cs @@ -9,7 +9,7 @@ namespace OpenLibraryNET.Data /// Holds data about recent changes made to OpenLibrary's data. /// [CollectionValueEquality] - public sealed partial record OLRecentChangesData : OLContainer + public partial record OLRecentChangesData : OLContainer { /// /// The ID of the change made. @@ -55,7 +55,7 @@ public IReadOnlyList Changes /// Holds data about the data entries that were changed. /// [CollectionValueEquality] - public sealed partial record OLChangeData : OLContainer + public partial record OLChangeData : OLContainer { /// /// The key of the object that was changed. diff --git a/src/OLData/OLSeedData.cs b/src/OLData/OLSeedData.cs index 1b8672a..93d6b4a 100644 --- a/src/OLData/OLSeedData.cs +++ b/src/OLData/OLSeedData.cs @@ -9,7 +9,7 @@ namespace OpenLibraryNET.OLData /// Holds data about a list seed. /// [CollectionValueEquality] - public sealed partial record class OLSeedData : OLContainer + public partial record class OLSeedData : OLContainer { /// /// The ID of this seed. diff --git a/src/OLData/OLSubjectData.cs b/src/OLData/OLSubjectData.cs index cd9d3dd..66807b4 100644 --- a/src/OLData/OLSubjectData.cs +++ b/src/OLData/OLSubjectData.cs @@ -9,7 +9,7 @@ namespace OpenLibraryNET.Data /// Holds data about a subject. /// [CollectionValueEquality] - public sealed partial record OLSubjectData : OLContainer + public partial record OLSubjectData : OLContainer { /// /// The name of this subject. diff --git a/src/OLData/OLWorkData.cs b/src/OLData/OLWorkData.cs index c49dbc5..e8412b6 100644 --- a/src/OLData/OLWorkData.cs +++ b/src/OLData/OLWorkData.cs @@ -9,7 +9,7 @@ namespace OpenLibraryNET.Data /// Holds data about a work. /// [CollectionValueEquality] - public sealed partial record OLWorkData : OLContainer + public partial record OLWorkData : OLContainer { /// /// The ID of the work. diff --git a/src/OLEdition.cs b/src/OLEdition.cs index 837c00b..81e7e42 100644 --- a/src/OLEdition.cs +++ b/src/OLEdition.cs @@ -9,7 +9,7 @@ namespace OpenLibraryNET /// Composite storage of various data related to an edition. /// [CollectionValueEquality] - public sealed partial record OLEdition + public partial record OLEdition { /// /// The ID of the edition. diff --git a/src/OLLoader/IOLMyBooksLoader.cs b/src/OLLoader/IOLMyBooksLoader.cs index 11b4d70..9ce2f69 100644 --- a/src/OLLoader/IOLMyBooksLoader.cs +++ b/src/OLLoader/IOLMyBooksLoader.cs @@ -13,7 +13,7 @@ public interface IOLMyBooksLoader /// /// The user to get the reading log of. null to use the username of the logged in account. /// The task object representing the asynchronous operation. - public Task<(bool, OLMyBooksData?)> TryGetWantToReadAsync(string? username = null); + public Task<(bool, OLMyBooksData?)> TryGetWantToReadAsync(string? username = null, params KeyValuePair[] parameters); /// /// Get data about a user's Want-To-Read reading log. @@ -24,14 +24,14 @@ public interface IOLMyBooksLoader /// /// /// - public Task GetWantToReadAsync(string? username = null); + public Task GetWantToReadAsync(string? username = null, params KeyValuePair[] parameters); /// /// Attempt to get data about a user's Currently-Reading reading log. /// /// The user to get the reading log of. null to use the username of the logged in account. /// The task object representing the asynchronous operation. - public Task<(bool, OLMyBooksData?)> TryGetCurrentlyReadingAsync(string? username = null); + public Task<(bool, OLMyBooksData?)> TryGetCurrentlyReadingAsync(string? username = null, params KeyValuePair[] parameters); /// /// Get data about a user's Currently-Reading reading log. @@ -42,14 +42,14 @@ public interface IOLMyBooksLoader /// /// /// - public Task GetCurrentlyReadingAsync(string? username = null); + public Task GetCurrentlyReadingAsync(string? username = null, params KeyValuePair[] parameters); /// /// Attempt to get data about a user's Already-Read reading log. /// /// The user to get the reading log of. null to use the username of the logged in account. /// The task object representing the asynchronous operation. - public Task<(bool, OLMyBooksData?)> TryGetAlreadyReadAsync(string? username = null); + public Task<(bool, OLMyBooksData?)> TryGetAlreadyReadAsync(string? username = null, params KeyValuePair[] parameters); /// /// Get data about a user's Already-Read reading log. @@ -60,7 +60,7 @@ public interface IOLMyBooksLoader /// /// /// - public Task GetAlreadyReadAsync(string? username = null); + public Task GetAlreadyReadAsync(string? username = null, params KeyValuePair[] parameters); /// /// Attempt to get data about a user's specified reading log. diff --git a/src/OLLoader/OLMyBooksLoader.cs b/src/OLLoader/OLMyBooksLoader.cs index f0b6c1c..8da2f99 100644 --- a/src/OLLoader/OLMyBooksLoader.cs +++ b/src/OLLoader/OLMyBooksLoader.cs @@ -17,9 +17,10 @@ public class OLMyBooksLoader : IOLMyBooksLoader /// Attempt to get data about a user's Want-To-Read reading log. /// /// The user to get the reading log of. null to use the username of the logged in account. + /// /// The task object representing the asynchronous operation. - public async Task<(bool, OLMyBooksData?)> TryGetWantToReadAsync(string? username = null) - => await TryGetWantToReadAsync(_client.BackingClient, username == null ? _client.Username?.ToLower()! : username); + public async Task<(bool, OLMyBooksData?)> TryGetWantToReadAsync(string? username = null, params KeyValuePair[] parameters) + => await TryGetWantToReadAsync(_client.BackingClient, username == null ? _client.Username?.ToLower()! : username , parameters); /// /// Get data about a user's Want-To-Read reading log. /// @@ -29,16 +30,16 @@ public class OLMyBooksLoader : IOLMyBooksLoader /// /// /// - public async Task GetWantToReadAsync(string? username = null) - => await GetWantToReadAsync(_client.BackingClient, username == null ? _client.Username?.ToLower()! : username); + public async Task GetWantToReadAsync(string? username = null, params KeyValuePair[] parameters) + => await GetWantToReadAsync(_client.BackingClient, username == null ? _client.Username?.ToLower()! : username,parameters); /// /// Attempt to get data about a user's Currently-Reading reading log. /// /// The user to get the reading log of. null to use the username of the logged in account. /// The task object representing the asynchronous operation. - public async Task<(bool, OLMyBooksData?)> TryGetCurrentlyReadingAsync(string? username = null) - => await TryGetCurrentlyReadingAsync(_client.BackingClient, username == null ? _client.Username?.ToLower()! : username); + public async Task<(bool, OLMyBooksData?)> TryGetCurrentlyReadingAsync(string? username = null, params KeyValuePair[] parameters) + => await TryGetCurrentlyReadingAsync(_client.BackingClient, username == null ? _client.Username?.ToLower()! : username, parameters); /// /// Get data about a user's Currently-Reading reading log. /// @@ -48,16 +49,16 @@ public class OLMyBooksLoader : IOLMyBooksLoader /// /// /// - public async Task GetCurrentlyReadingAsync(string? username = null) - => await GetCurrentlyReadingAsync(_client.BackingClient, username == null ? _client.Username?.ToLower()! : username); + public async Task GetCurrentlyReadingAsync(string? username = null, params KeyValuePair[] parameters) + => await GetCurrentlyReadingAsync(_client.BackingClient, username == null ? _client.Username?.ToLower()! : username, parameters); /// /// Attempt to get data about a user's Already-Read reading log. /// /// The user to get the reading log of. null to use the username of the logged in account. /// The task object representing the asynchronous operation. - public async Task<(bool, OLMyBooksData?)> TryGetAlreadyReadAsync(string? username = null) - => await TryGetAlreadyReadAsync(_client.BackingClient, username == null ? _client.Username?.ToLower()! : username); + public async Task<(bool, OLMyBooksData?)> TryGetAlreadyReadAsync(string? username = null, params KeyValuePair[] parameters) + => await TryGetAlreadyReadAsync(_client.BackingClient, username == null ? _client.Username?.ToLower()! : username, parameters ); /// /// Get data about a user's Already-Read reading log. /// @@ -67,8 +68,8 @@ public class OLMyBooksLoader : IOLMyBooksLoader /// /// /// - public async Task GetAlreadyReadAsync(string? username = null) - => await GetAlreadyReadAsync(_client.BackingClient, username == null ? _client.Username?.ToLower()! : username); + public async Task GetAlreadyReadAsync(string? username = null, params KeyValuePair[] parameters ) + => await GetAlreadyReadAsync(_client.BackingClient, username == null ? _client.Username?.ToLower()! : username,parameters); /// /// Attempt to get data about a user's specified reading log. @@ -131,9 +132,9 @@ public class OLMyBooksLoader : IOLMyBooksLoader /// An HttpClient instance which will be used to make the request. /// The user to get the reading log of. /// The task object representing the asynchronous operation. - public async static Task<(bool, OLMyBooksData?)> TryGetWantToReadAsync(HttpClient client, string username) + public async static Task<(bool, OLMyBooksData?)> TryGetWantToReadAsync(HttpClient client, string username, params KeyValuePair[] parameters) { - try { return (true, await GetWantToReadAsync(client, username)); } + try { return (true, await GetWantToReadAsync(client, username, parameters)); } catch { return (false, null); } } @@ -147,12 +148,12 @@ public class OLMyBooksLoader : IOLMyBooksLoader /// /// /// - public async static Task GetWantToReadAsync(HttpClient client, string username) + public async static Task GetWantToReadAsync(HttpClient client, string username, params KeyValuePair[] parameters) { return await OpenLibraryUtility.LoadAsync ( client, - OpenLibraryUtility.BuildMyBooksUri(username, "want-to-read") + OpenLibraryUtility.BuildMyBooksUri(username, "want-to-read",parameters) ); } @@ -162,9 +163,9 @@ public class OLMyBooksLoader : IOLMyBooksLoader /// An HttpClient instance which will be used to make the request. /// The user to get the reading log of. /// The task object representing the asynchronous operation. - public async static Task<(bool, OLMyBooksData?)> TryGetCurrentlyReadingAsync(HttpClient client, string username) + public async static Task<(bool, OLMyBooksData?)> TryGetCurrentlyReadingAsync(HttpClient client, string username, params KeyValuePair[] parameters) { - try { return (true, await GetCurrentlyReadingAsync(client, username)); } + try { return (true, await GetCurrentlyReadingAsync(client, username,parameters)); } catch { return (false, null); } } @@ -178,12 +179,12 @@ public class OLMyBooksLoader : IOLMyBooksLoader /// /// /// - public async static Task GetCurrentlyReadingAsync(HttpClient client, string username) + public async static Task GetCurrentlyReadingAsync(HttpClient client, string username, params KeyValuePair[] parameters) { return await OpenLibraryUtility.LoadAsync ( client, - OpenLibraryUtility.BuildMyBooksUri(username, "currently-reading") + OpenLibraryUtility.BuildMyBooksUri(username, "currently-reading",parameters) ); } @@ -193,9 +194,9 @@ public class OLMyBooksLoader : IOLMyBooksLoader /// An HttpClient instance which will be used to make the request. /// The user to get the reading log of. /// The task object representing the asynchronous operation. - public async static Task<(bool, OLMyBooksData?)> TryGetAlreadyReadAsync(HttpClient client, string username) + public async static Task<(bool, OLMyBooksData?)> TryGetAlreadyReadAsync(HttpClient client, string username, params KeyValuePair[] parameters) { - try { return (true, await GetAlreadyReadAsync(client, username)); } + try { return (true, await GetAlreadyReadAsync(client, username, parameters)); } catch { return (false, null); } } @@ -209,12 +210,12 @@ public class OLMyBooksLoader : IOLMyBooksLoader /// /// /// - public async static Task GetAlreadyReadAsync(HttpClient client, string username) + public async static Task GetAlreadyReadAsync(HttpClient client, string username, params KeyValuePair[] parameters) { return await OpenLibraryUtility.LoadAsync ( client, - OpenLibraryUtility.BuildMyBooksUri(username, "already-read") + OpenLibraryUtility.BuildMyBooksUri(username, "already-read", parameters) ); } diff --git a/src/OLWork.cs b/src/OLWork.cs index c8d3fd1..d90543d 100644 --- a/src/OLWork.cs +++ b/src/OLWork.cs @@ -10,7 +10,7 @@ namespace OpenLibraryNET /// Composite storage of various data related to a work. /// [CollectionValueEquality] - public sealed partial record OLWork + public partial record OLWork { /// /// The ID of the work. diff --git a/src/OpenLibraryClient.cs b/src/OpenLibraryClient.cs index ca42b11..cd55f85 100644 --- a/src/OpenLibraryClient.cs +++ b/src/OpenLibraryClient.cs @@ -1,15 +1,24 @@ -using System.Formats.Asn1; +using System; +using System.Formats.Asn1; using System.Net; using System.Net.Http.Json; using System.Text.RegularExpressions; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Http.Diagnostics; +using Microsoft.Extensions.Http.Resilience; +using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OpenLibraryNET.Data; using OpenLibraryNET.Loader; using OpenLibraryNET.Utility; +using Polly; namespace OpenLibraryNET { + + + /// /// The main interface to OpenLibrary.
/// Instantiates HttpClient internally, as OpenLibraryClient uses cookies.
@@ -17,6 +26,9 @@ namespace OpenLibraryNET ///
public class OpenLibraryClient : IOpenLibraryClient { + + + /// public bool LoggedIn => _httpHandler.CookieContainer.GetCookies(OpenLibraryUtility.BaseUri).SingleOrDefault(cookie => cookie.Name == "session") != null; /// @@ -46,15 +58,51 @@ public class OpenLibraryClient : IOpenLibraryClient /// public HttpClient BackingClient => _httpClient; + private class OperationKeyHandler : DelegatingHandler + { + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + ResilienceContext context = ResilienceContextPool.Shared.Get(cancellationToken); + string uri = request.RequestUri.ToString(); + ResilienceContextExtensions.SetRequestMetadata(context, new RequestMetadata("OperationKey", uri, "Additional information if needed")); + return await base.SendAsync(request, cancellationToken); + } + } + + private const string httpClientName = "OpenLibraryNET.OpenLibraryClient"; + + private readonly CookieContainer? _cookieContainer = new CookieContainer(); + + private readonly IHttpClientFactory _httpClientFactory; + /// /// Create a new instance of the OpenLibraryClient.
/// Instantiates HttpClient internally, as OpenLibraryClient uses cookies.
/// To reuse the backing HttpClient, reuse the OpenLibrary instance. ///
- public OpenLibraryClient() + public OpenLibraryClient(Action? configureOptions = null, Action? logBuilder = null) { - _httpHandler = new HttpClientHandler() { AllowAutoRedirect = true, UseCookies = true }; - _httpClient = new HttpClient(_httpHandler); + ServiceCollection services = new ServiceCollection(); + _httpHandler = new HttpClientHandler + { + AllowAutoRedirect = true, + UseCookies = true, + CookieContainer = _cookieContainer + }; + if (configureOptions == null) configureOptions = new Action(options => options.TotalRequestTimeout = new HttpTimeoutStrategyOptions()); + + services.AddHttpClient(httpClientName) + .ConfigurePrimaryHttpMessageHandler(() => _httpHandler) + .AddStandardResilienceHandler(configureOptions); + //.AddHttpMessageHandler()); + + if (logBuilder != null) + { + services.AddLogging(logBuilder); + } + ServiceProvider provider = services.BuildServiceProvider(); + _httpClientFactory = provider.GetService(); + _httpClient = _httpClientFactory.CreateClient(httpClientName); _work = new OLWorkLoader(_httpClient); _author = new OLAuthorLoader(_httpClient); diff --git a/src/OpenLibraryNET.csproj b/src/OpenLibraryNET.csproj index 0071a3a..c749a2f 100644 --- a/src/OpenLibraryNET.csproj +++ b/src/OpenLibraryNET.csproj @@ -1,10 +1,10 @@ - + - net6.0 + net10.0 enable enable - + 1.0.0.0