mirror of
https://github.com/JKorf/CryptoExchange.Net
synced 2026-02-16 22:23:54 +00:00
wip
This commit is contained in:
parent
42736f3003
commit
bb2f6c0a14
@ -5,40 +5,36 @@ using System.Text;
|
|||||||
namespace CryptoExchange.Net.Converters.MessageParsing.DynamicConverters
|
namespace CryptoExchange.Net.Converters.MessageParsing.DynamicConverters
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Message evaluator
|
/// Message type definition
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MessageEvaluator
|
public class MessageTypeDefinition
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The priority of this evaluator, higher prio evaluators (with lower Priority number) will be checked for matches before lower ones
|
/// Whether to immediately select the definition when it is matched. Can only be used when the evaluator has a single unique field to look for
|
||||||
/// </summary>
|
|
||||||
public int Priority { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// Whether to immediately match the evaluator when it is matched. Can only be used when the evaluator has a single unique field to look for
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ForceIfFound { get; set; }
|
public bool ForceIfFound { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The fields this evaluator has to look for
|
/// The fields a message needs to contain for this definition
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public MessageFieldReference[] Fields { get; set; } = [];
|
public MessageFieldReference[] Fields { get; set; } = [];
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The callback for getting the identifier string
|
/// The callback for getting the identifier string
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Func<SearchResult, string>? IdentifyMessageCallback { get; set; }
|
public Func<SearchResult, string>? TypeIdentifierCallback { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The static identifier string to return when this evaluator is matched
|
/// The static identifier string to return when this evaluator is matched
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? StaticIdentifier { get; set; }
|
public string? StaticIdentifier { get; set; }
|
||||||
|
|
||||||
internal string? IdentifyMessage(SearchResult result)
|
internal string? GetMessageType(SearchResult result)
|
||||||
{
|
{
|
||||||
if (StaticIdentifier != null)
|
if (StaticIdentifier != null)
|
||||||
return StaticIdentifier;
|
return StaticIdentifier;
|
||||||
|
|
||||||
return IdentifyMessageCallback!(result);
|
return TypeIdentifierCallback!(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool Statisfied(SearchResult result)
|
internal bool Satisfied(SearchResult result)
|
||||||
{
|
{
|
||||||
foreach(var field in Fields)
|
foreach(var field in Fields)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -9,7 +9,7 @@ namespace CryptoExchange.Net.Converters.MessageParsing.DynamicConverters
|
|||||||
public bool SkipReading { get; set; }
|
public bool SkipReading { get; set; }
|
||||||
public bool OverlappingField { get; set; }
|
public bool OverlappingField { get; set; }
|
||||||
public MessageFieldReference Field { get; set; }
|
public MessageFieldReference Field { get; set; }
|
||||||
public MessageEvaluator? ForceEvaluator { get; set; }
|
public MessageTypeDefinition? ForceEvaluator { get; set; }
|
||||||
|
|
||||||
public MessageEvalutorFieldReference(MessageFieldReference field)
|
public MessageEvalutorFieldReference(MessageFieldReference field)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -20,7 +20,82 @@ namespace CryptoExchange.Net.Converters.MessageParsing.DynamicConverters
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Callback to check if the field value matches an expected constraint
|
/// Callback to check if the field value matches an expected constraint
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Func<string?, bool>? Constraint { get; set; }
|
public Func<string?, bool>? Constraint { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether the value is one of the string values in the set
|
||||||
|
/// </summary>
|
||||||
|
public MessageFieldReference WithFilterContstraint(HashSet<string?> set)
|
||||||
|
{
|
||||||
|
Constraint = set.Contains;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether the value is equal to a string
|
||||||
|
/// </summary>
|
||||||
|
public MessageFieldReference WithEqualContstraint(string compare)
|
||||||
|
{
|
||||||
|
Constraint = x => x != null && x.Equals(compare, StringComparison.Ordinal);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether the value is not equal to a string
|
||||||
|
/// </summary>
|
||||||
|
public MessageFieldReference WithNotEqualContstraint(string compare)
|
||||||
|
{
|
||||||
|
Constraint = x => x == null || !x.Equals(compare, StringComparison.Ordinal);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether the value is not null
|
||||||
|
/// </summary>
|
||||||
|
public MessageFieldReference WithNotNullContstraint()
|
||||||
|
{
|
||||||
|
Constraint = x => x != null;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether the value starts with a certain string
|
||||||
|
/// </summary>
|
||||||
|
public MessageFieldReference WithStartsWithContstraint(string start)
|
||||||
|
{
|
||||||
|
Constraint = x => x != null && x.StartsWith(start, StringComparison.Ordinal);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether the value starts with a certain string
|
||||||
|
/// </summary>
|
||||||
|
public MessageFieldReference WithStartsWithContstraints(params string[] startValues)
|
||||||
|
{
|
||||||
|
Constraint = x =>
|
||||||
|
{
|
||||||
|
if (x == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
foreach (var item in startValues)
|
||||||
|
{
|
||||||
|
if (x!.StartsWith(item, StringComparison.Ordinal))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether the value starts with a certain string
|
||||||
|
/// </summary>
|
||||||
|
public MessageFieldReference WithCustomContstraint(Func<string?, bool> constraint)
|
||||||
|
{
|
||||||
|
Constraint = constraint;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
|
|||||||
@ -1,8 +1,5 @@
|
|||||||
using CryptoExchange.Net.Converters.MessageParsing.DynamicConverters;
|
using CryptoExchange.Net.Converters.MessageParsing.DynamicConverters;
|
||||||
using System;
|
using System;
|
||||||
#if !NETSTANDARD
|
|
||||||
using System.Collections.Frozen;
|
|
||||||
#endif
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -22,18 +19,17 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract JsonSerializerOptions Options { get; }
|
public abstract JsonSerializerOptions Options { get; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Message evaluators
|
/// Message evaluators
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected abstract MessageEvaluator[] TypeEvaluators { get; }
|
protected abstract MessageTypeDefinition[] TypeEvaluators { get; }
|
||||||
|
|
||||||
private readonly SearchResult _searchResult = new();
|
private readonly SearchResult _searchResult = new();
|
||||||
|
|
||||||
private bool _hasArraySearches;
|
private bool _hasArraySearches;
|
||||||
private bool _initialized;
|
private bool _initialized;
|
||||||
private int _maxSearchDepth;
|
private int _maxSearchDepth;
|
||||||
private MessageEvaluator? _topEvaluator;
|
private MessageTypeDefinition? _topEvaluator;
|
||||||
private List<MessageEvalutorFieldReference>? _searchFields;
|
private List<MessageEvalutorFieldReference>? _searchFields;
|
||||||
private Dictionary<Type, Func<object, string?>>? _baseTypeMapping;
|
private Dictionary<Type, Func<object, string?>>? _baseTypeMapping;
|
||||||
private Dictionary<Type, Func<object, string?>>? _mapping;
|
private Dictionary<Type, Func<object, string?>>? _mapping;
|
||||||
@ -56,7 +52,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
|||||||
|
|
||||||
_maxSearchDepth = int.MinValue;
|
_maxSearchDepth = int.MinValue;
|
||||||
_searchFields = new List<MessageEvalutorFieldReference>();
|
_searchFields = new List<MessageEvalutorFieldReference>();
|
||||||
foreach (var evaluator in TypeEvaluators.OrderBy(x => x.Priority))
|
foreach (var evaluator in TypeEvaluators)
|
||||||
{
|
{
|
||||||
_topEvaluator ??= evaluator;
|
_topEvaluator ??= evaluator;
|
||||||
foreach (var field in evaluator.Fields)
|
foreach (var field in evaluator.Fields)
|
||||||
@ -105,7 +101,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
|||||||
foreach(var sameSearchField in existingSameSearchField)
|
foreach(var sameSearchField in existingSameSearchField)
|
||||||
{
|
{
|
||||||
if (sameSearchField.SkipReading == true
|
if (sameSearchField.SkipReading == true
|
||||||
&& (evaluator.IdentifyMessageCallback != null || field.Constraint != null))
|
&& (evaluator.TypeIdentifierCallback != null || field.Constraint != null))
|
||||||
{
|
{
|
||||||
sameSearchField.SkipReading = false;
|
sameSearchField.SkipReading = false;
|
||||||
}
|
}
|
||||||
@ -121,7 +117,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
|||||||
|
|
||||||
_searchFields.Add(new MessageEvalutorFieldReference(field)
|
_searchFields.Add(new MessageEvalutorFieldReference(field)
|
||||||
{
|
{
|
||||||
SkipReading = evaluator.IdentifyMessageCallback == null && field.Constraint == null,
|
SkipReading = evaluator.TypeIdentifierCallback == null && field.Constraint == null,
|
||||||
ForceEvaluator = !existingSameSearchField.Any() ? (evaluator.ForceIfFound ? evaluator : null) : null,
|
ForceEvaluator = !existingSameSearchField.Any() ? (evaluator.ForceIfFound ? evaluator : null) : null,
|
||||||
OverlappingField = overlapping.Any()
|
OverlappingField = overlapping.Any()
|
||||||
});
|
});
|
||||||
@ -309,7 +305,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
|||||||
return field.ForceEvaluator.StaticIdentifier;
|
return field.ForceEvaluator.StaticIdentifier;
|
||||||
|
|
||||||
// Force the immediate return upon encountering this field
|
// Force the immediate return upon encountering this field
|
||||||
return field.ForceEvaluator.IdentifyMessage(_searchResult);
|
return field.ForceEvaluator.GetMessageType(_searchResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
written = true;
|
written = true;
|
||||||
@ -320,8 +316,8 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
|||||||
if (!written)
|
if (!written)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (_topEvaluator!.Statisfied(_searchResult))
|
if (_topEvaluator!.Satisfied(_searchResult))
|
||||||
return _topEvaluator.IdentifyMessage(_searchResult);
|
return _topEvaluator.GetMessageType(_searchResult);
|
||||||
|
|
||||||
if (_searchFields.Count == _searchResult.Count)
|
if (_searchFields.Count == _searchResult.Count)
|
||||||
break;
|
break;
|
||||||
@ -330,8 +326,8 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
|||||||
|
|
||||||
foreach (var evaluator in TypeEvaluators)
|
foreach (var evaluator in TypeEvaluators)
|
||||||
{
|
{
|
||||||
if (evaluator.Statisfied(_searchResult))
|
if (evaluator.Satisfied(_searchResult))
|
||||||
return evaluator.IdentifyMessage(_searchResult);
|
return evaluator.GetMessageType(_searchResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user