Regex experimentation (#128)
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Speckle.Sdk.Helpers;
|
||||
|
||||
public static class Constants
|
||||
@@ -7,6 +5,4 @@ public static class Constants
|
||||
public const double EPS = 1e-5;
|
||||
public const double SMALL_EPS = 1e-8;
|
||||
public const double EPS_SQUARED = EPS * EPS;
|
||||
|
||||
public static readonly Regex ChunkPropertyNameRegex = new(@"^@\((\d*)\)"); //TODO: Experiment with compiled flag
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Speckle.Sdk.Helpers;
|
||||
|
||||
public static
|
||||
#if NET7_0_OR_GREATER
|
||||
partial
|
||||
#endif
|
||||
class PropNameValidator
|
||||
{
|
||||
private const string CHUNK_PROPERTY_NAME_REGEX_STRING = @"^@\((\d*)\)";
|
||||
|
||||
#if NET7_0_OR_GREATER
|
||||
[GeneratedRegex(CHUNK_PROPERTY_NAME_REGEX_STRING)]
|
||||
private static partial Regex ChunkRegex();
|
||||
|
||||
private static readonly Regex ChunkPropertyNameRegex = ChunkRegex();
|
||||
#else
|
||||
private static readonly Regex ChunkPropertyNameRegex = new(CHUNK_PROPERTY_NAME_REGEX_STRING);
|
||||
#endif
|
||||
|
||||
public static bool IsChunkable(string propName, out int chunkSize)
|
||||
{
|
||||
if (ChunkPropertyNameRegex.IsMatch(propName))
|
||||
{
|
||||
var match = ChunkPropertyNameRegex.Match(propName);
|
||||
var isChunkable = int.TryParse(match.Groups[^1].Value, out chunkSize);
|
||||
return isChunkable;
|
||||
}
|
||||
|
||||
chunkSize = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
[Pure]
|
||||
public static bool IsDetached(string propName) =>
|
||||
#if NET5_0_OR_GREATER
|
||||
propName.StartsWith('@');
|
||||
#else
|
||||
propName.StartsWith("@");
|
||||
#endif
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Collections;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using Speckle.Newtonsoft.Json;
|
||||
using Speckle.Newtonsoft.Json.Linq;
|
||||
using Speckle.Sdk.Common;
|
||||
@@ -25,8 +24,6 @@ namespace Speckle.Sdk.Models;
|
||||
[SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Serialized property names are camelCase by design")]
|
||||
public class Base : DynamicBase, ISpeckleObject
|
||||
{
|
||||
private static readonly Regex s_chunkSyntax = Constants.ChunkPropertyNameRegex;
|
||||
|
||||
private string _type;
|
||||
|
||||
/// <summary>
|
||||
@@ -133,21 +130,14 @@ public class Base : DynamicBase, ISpeckleObject
|
||||
var dynamicProps = @base.DynamicPropertyKeys;
|
||||
foreach (var propName in dynamicProps)
|
||||
{
|
||||
#if NETSTANDARD2_0
|
||||
if (!propName.StartsWith("@"))
|
||||
#else
|
||||
if (!propName.StartsWith('@'))
|
||||
#endif
|
||||
if (!PropNameValidator.IsDetached(propName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Simplfied dynamic prop chunking handling
|
||||
if (s_chunkSyntax.IsMatch(propName))
|
||||
if (PropNameValidator.IsChunkable(propName, out int chunkSize))
|
||||
{
|
||||
var match = s_chunkSyntax.Match(propName);
|
||||
_ = int.TryParse(match.Groups[^1].Value, out int chunkSize);
|
||||
|
||||
if (chunkSize != -1 && @base[propName] is IList asList)
|
||||
{
|
||||
count += asList.Count / chunkSize;
|
||||
|
||||
@@ -16,5 +16,5 @@ public sealed class ObjectReference : Base
|
||||
{
|
||||
public required string referencedId { get; init; }
|
||||
|
||||
public Dictionary<string, int> closure { get; set; }
|
||||
public Dictionary<string, int>? closure { get; set; }
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ using Speckle.Sdk.Common;
|
||||
using Speckle.Sdk.Helpers;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Transports;
|
||||
using Constants = Speckle.Sdk.Helpers.Constants;
|
||||
|
||||
namespace Speckle.Sdk.Serialisation;
|
||||
|
||||
@@ -131,7 +130,7 @@ public class SpeckleObjectSerializer
|
||||
// Note: this change was needed as we've made the ObjectReference type inherit from Base for
|
||||
// the purpose of the "do not convert unchanged previously converted objects" POC.
|
||||
case ObjectReference r:
|
||||
Dictionary<string, object> ret =
|
||||
Dictionary<string, object?> ret =
|
||||
new()
|
||||
{
|
||||
["speckle_type"] = r.speckle_type,
|
||||
@@ -322,19 +321,12 @@ public class SpeckleObjectSerializer
|
||||
}
|
||||
|
||||
object? baseValue = baseObj[propName];
|
||||
#if NETSTANDARD2_0
|
||||
bool isDetachable = propName.StartsWith("@");
|
||||
#else
|
||||
bool isDetachable = propName.StartsWith('@');
|
||||
#endif
|
||||
bool isChunkable = false;
|
||||
int chunkSize = 1000;
|
||||
|
||||
if (Constants.ChunkPropertyNameRegex.IsMatch(propName))
|
||||
{
|
||||
var match = Constants.ChunkPropertyNameRegex.Match(propName);
|
||||
isChunkable = int.TryParse(match.Groups[^1].Value, out chunkSize);
|
||||
}
|
||||
bool isDetachable = PropNameValidator.IsDetached(propName);
|
||||
|
||||
int chunkSize = 1000;
|
||||
bool isChunkable = isDetachable && PropNameValidator.IsChunkable(propName, out chunkSize);
|
||||
|
||||
allProperties[propName] = (baseValue, new PropertyAttributeInfo(isDetachable, isChunkable, chunkSize, null));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user