diff --git a/CryptoExchange.Net.UnitTests/ExchangeHelpersTests.cs b/CryptoExchange.Net.UnitTests/ExchangeHelpersTests.cs index bdb8501..403f85e 100644 --- a/CryptoExchange.Net.UnitTests/ExchangeHelpersTests.cs +++ b/CryptoExchange.Net.UnitTests/ExchangeHelpersTests.cs @@ -1,6 +1,7 @@ using CryptoExchange.Net.Objects; using NUnit.Framework; using NUnit.Framework.Legacy; +using System.Diagnostics; using System.Globalization; namespace CryptoExchange.Net.UnitTests @@ -70,5 +71,20 @@ namespace CryptoExchange.Net.UnitTests var result = ExchangeHelpers.Normalize(input); Assert.That(expected == result.ToString(CultureInfo.InvariantCulture)); } + + [Test] + [TestCase("123", "BKR", 32, true, "BKR|JK|123")] + [TestCase("123", "BKR", 32, false, "123")] + [TestCase("123123123123123123123123123123", "BKR", 32, true, "123123123123123123123123123123")] // 30 + [TestCase("123123123123123123123123123", "BKR", 32, true, "123123123123123123123123123")] // 27 + [TestCase("1231231231231231231231231", "BKR", 32, true, "BKR|JK|1231231231231231231231231")] // 25 + [TestCase(null, "BKR", 32, true, null)] + public void ApplyBrokerIdTests(string clientOrderId, string brokerId, int maxLength, bool allowValueAdjustement, string expected) + { + var result = LibraryHelpers.ApplyBrokerId(clientOrderId, brokerId, maxLength, allowValueAdjustement); + + if (expected != null) + Assert.That(result, Is.EqualTo(expected)); + } } } diff --git a/CryptoExchange.Net/Converters/SystemTextJson/JsonConverterCtorAttribute.cs b/CryptoExchange.Net/Converters/SystemTextJson/JsonConverterCtorAttribute.cs new file mode 100644 index 0000000..48c4240 --- /dev/null +++ b/CryptoExchange.Net/Converters/SystemTextJson/JsonConverterCtorAttribute.cs @@ -0,0 +1,27 @@ +using System; +using System.Text.Json.Serialization; + +namespace CryptoExchange.Net.Converters.SystemTextJson +{ + /// + /// Attribute for allowing specifying a JsonConverter with constructor parameters + /// + /// + [AttributeUsage(AttributeTargets.Property)] + public class JsonConverterCtorAttribute : JsonConverterAttribute where T : JsonConverter + { + private readonly object[] _parameters; + + /// + /// ctor + /// + public JsonConverterCtorAttribute(params object[] parameters) => _parameters = parameters; + + /// + public override JsonConverter CreateConverter(Type typeToConvert) + { + return (T)Activator.CreateInstance(typeof(T), _parameters); + } + } + +} diff --git a/CryptoExchange.Net/Converters/SystemTextJson/ReplaceConverter.cs b/CryptoExchange.Net/Converters/SystemTextJson/ReplaceConverter.cs new file mode 100644 index 0000000..5976387 --- /dev/null +++ b/CryptoExchange.Net/Converters/SystemTextJson/ReplaceConverter.cs @@ -0,0 +1,41 @@ +using System; +using System.Linq; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace CryptoExchange.Net.Converters.SystemTextJson +{ + /// + /// Replace a value on a string property + /// + public class ReplaceConverter : JsonConverter + { + private readonly (string ValueToReplace, string ValueToReplaceWith)[] _replacementSets; + + /// + /// ctor + /// + public ReplaceConverter(params string[] replaceSets) + { + _replacementSets = replaceSets.Select(x => + { + var split = x.Split(new string[] { "->" }, StringSplitOptions.None); + if (split.Length != 2) + throw new ArgumentException("Invalid replacement config"); + return (split[0], split[1]); + }).ToArray(); + } + + /// + public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var value = reader.GetString(); + foreach (var set in _replacementSets) + value = value?.Replace(set.ValueToReplace, set.ValueToReplaceWith); + return value; + } + + /// + public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) => writer.WriteStringValue(value); + } +} diff --git a/CryptoExchange.Net/CryptoExchange.Net.csproj b/CryptoExchange.Net/CryptoExchange.Net.csproj index 6ff68b9..b3a0935 100644 --- a/CryptoExchange.Net/CryptoExchange.Net.csproj +++ b/CryptoExchange.Net/CryptoExchange.Net.csproj @@ -20,7 +20,7 @@ true https://github.com/JKorf/CryptoExchange.Net?tab=readme-ov-file#release-notes enable - 10.0 + 12.0 MIT diff --git a/CryptoExchange.Net/LibraryHelpers.cs b/CryptoExchange.Net/LibraryHelpers.cs new file mode 100644 index 0000000..ba8b008 --- /dev/null +++ b/CryptoExchange.Net/LibraryHelpers.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace CryptoExchange.Net +{ + /// + /// Helpers for client libraries + /// + public static class LibraryHelpers + { + /// + /// Client order id seperator + /// + public const string ClientOrderIdSeperator = "|JK|"; + + /// + /// Apply broker id to a client order id + /// + /// + /// + /// + /// + /// + public static string ApplyBrokerId(string? clientOrderId, string brokerId, int maxLength, bool allowValueAdjustement) + { + var reservedLength = brokerId.Length + ClientOrderIdSeperator.Length; + + if ((clientOrderId?.Length + reservedLength) > maxLength) + return clientOrderId!; + + if (!string.IsNullOrEmpty(clientOrderId)) + { + if (allowValueAdjustement) + clientOrderId = brokerId + ClientOrderIdSeperator + clientOrderId; + + return clientOrderId!; + } + else + { + clientOrderId = ExchangeHelpers.AppendRandomString(brokerId + ClientOrderIdSeperator, maxLength); + } + + return clientOrderId; + } + } +}