Skip to content

Commit

Permalink
Merge pull request #24 from NatVanG/drillthroughjsonpointer
Browse files Browse the repository at this point in the history
Drillthrough jsonpointer in rules data mapping part.
  • Loading branch information
NatVanG authored Nov 19, 2023
2 parents a6caee9 + cf63b62 commit d6dd501
Show file tree
Hide file tree
Showing 11 changed files with 941 additions and 137 deletions.
86 changes: 86 additions & 0 deletions PBIXInspectorLibrary/CustomRules/SetDifferenceRule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using Json.Logic;
using Json.More;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;


namespace PBIXInspectorLibrary.CustomRules;

/// <summary>
/// Handles the `diff` operation.
/// </summary>
[Operator("diff")]
[JsonConverter(typeof(SetDifferenceRuleJsonConverter))]
public class SetDifferenceRule : Json.Logic.Rule
{
internal Json.Logic.Rule Set1 { get; }
internal Json.Logic.Rule Set2 { get; }

public SetDifferenceRule(Json.Logic.Rule set1, Json.Logic.Rule set2)
{
Set1 = set1;
Set2 = set2;
}

/// <summary>
/// Applies the rule to the input data.
/// </summary>
/// <param name="data">The input data.</param>
/// <param name="contextData">
/// Optional secondary data. Used by a few operators to pass a secondary
/// data context to inner operators.
/// </param>
/// <returns>The result of the rule.</returns>
public override JsonNode? Apply(JsonNode? data, JsonNode? contextData = null)
{
var set1 = Set1.Apply(data, contextData);
var set2 = Set2.Apply(data, contextData);

if (set1 is not JsonArray || set2 is not JsonArray)
return new JsonArray();

var arr1 = (JsonArray)set1;
var arr2 = (JsonArray)set2;

var difference = new JsonArray();

foreach (var item in arr1)
{
if (!arr2.Any(x => item.IsEquivalentTo(x)))
{
var copy = item.Copy();
if (!difference.Any(x => x.IsEquivalentTo(copy)))
{
difference.Add(copy);
}
}
}

return difference;
}
}

internal class SetDifferenceRuleJsonConverter : JsonConverter<SetDifferenceRule>
{
public override SetDifferenceRule? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var parameters = JsonSerializer.Deserialize<Json.Logic.Rule[]>(ref reader, options);

if (parameters is not { Length: 2 })
throw new JsonException("The difference rule needs an array with 2 parameters.");

return new SetDifferenceRule(parameters[0], parameters[1]);
}

public override void Write(Utf8JsonWriter writer, SetDifferenceRule value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WritePropertyName("difference");
writer.WriteStartArray();
writer.WriteRule(value.Set1, options);
writer.WriteRule(value.Set2, options);
writer.WriteEndArray();
writer.WriteEndObject();
}
}
90 changes: 90 additions & 0 deletions PBIXInspectorLibrary/CustomRules/SetEqualRule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using Json.Logic;
using Json.More;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;


namespace PBIXInspectorLibrary.CustomRules;

/// <summary>
/// Handles the `equalsets` operation.
/// </summary>
[Operator("equalsets")]
[JsonConverter(typeof(SetEqualRuleJsonConverter))]
public class SetEqualRule : Json.Logic.Rule
{
internal Json.Logic.Rule Set1 { get; }
internal Json.Logic.Rule Set2 { get; }

public SetEqualRule(Json.Logic.Rule set1, Json.Logic.Rule set2)
{
Set1 = set1;
Set2 = set2;
}

/// <summary>
/// Applies the rule to the input data.
/// </summary>
/// <param name="data">The input data.</param>
/// <param name="contextData">
/// Optional secondary data. Used by a few operators to pass a secondary
/// data context to inner operators.
/// </param>
/// <returns>The result of the rule.</returns>
public override JsonNode? Apply(JsonNode? data, JsonNode? contextData = null)
{
var set1 = Set1.Apply(data, contextData);
var set2 = Set2.Apply(data, contextData);

if (set1 is not JsonArray || set2 is not JsonArray)
return new JsonArray();

var arr1 = (JsonArray)set1;
var arr2 = (JsonArray)set2;

var symmetricDifference = new JsonArray();

foreach (var item in arr1)
{
if (!arr2.Any(x => item.IsEquivalentTo(x)))
{
return false;
}
}

foreach (var item in arr2)
{
if (!arr1.Any(x => item.IsEquivalentTo(x)))
{
return false;
}
}

return true;
}
}

internal class SetEqualRuleJsonConverter : JsonConverter<SetEqualRule>
{
public override SetEqualRule? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var parameters = JsonSerializer.Deserialize<Json.Logic.Rule[]>(ref reader, options);

if (parameters is not { Length: 2 })
throw new JsonException("The symdiff rule needs an array with 2 parameters.");

return new SetEqualRule(parameters[0], parameters[1]);
}

public override void Write(Utf8JsonWriter writer, SetEqualRule value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WritePropertyName("symdiff");
writer.WriteStartArray();
writer.WriteRule(value.Set1, options);
writer.WriteRule(value.Set2, options);
writer.WriteEndArray();
writer.WriteEndObject();
}
}
86 changes: 86 additions & 0 deletions PBIXInspectorLibrary/CustomRules/SetIntersectionRule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using Json.Logic;
using Json.More;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;


namespace PBIXInspectorLibrary.CustomRules;

/// <summary>
/// Handles the `intersection` operation.
/// </summary>
[Operator("intersection")]
[JsonConverter(typeof(SetIntersectionRuleJsonConverter))]
public class SetIntersectionRule : Json.Logic.Rule
{
internal Json.Logic.Rule Set1 { get; }
internal Json.Logic.Rule Set2 { get; }

public SetIntersectionRule(Json.Logic.Rule set1, Json.Logic.Rule set2)
{
Set1 = set1;
Set2 = set2;
}

/// <summary>
/// Applies the rule to the input data.
/// </summary>
/// <param name="data">The input data.</param>
/// <param name="contextData">
/// Optional secondary data. Used by a few operators to pass a secondary
/// data context to inner operators.
/// </param>
/// <returns>The result of the rule.</returns>
public override JsonNode? Apply(JsonNode? data, JsonNode? contextData = null)
{
var set1 = Set1.Apply(data, contextData);
var set2 = Set2.Apply(data, contextData);

if (set1 is not JsonArray || set2 is not JsonArray)
return new JsonArray();

var arr1 = (JsonArray)set1;
var arr2 = (JsonArray)set2;

var intersection = new JsonArray();

foreach (var item in arr1)
{
if (arr2.Any(x => item.IsEquivalentTo(x)))
{
var copy = item.Copy();
if (!intersection.Any(x => x.IsEquivalentTo(copy)))
{
intersection.Add(copy);
}
}
}

return intersection;
}
}

internal class SetIntersectionRuleJsonConverter : JsonConverter<SetIntersectionRule>
{
public override SetIntersectionRule? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var parameters = JsonSerializer.Deserialize<Json.Logic.Rule[]>(ref reader, options);

if (parameters is not { Length: 2 })
throw new JsonException("The intersection rule needs an array with 2 parameters.");

return new SetIntersectionRule(parameters[0], parameters[1]);
}

public override void Write(Utf8JsonWriter writer, SetIntersectionRule value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WritePropertyName("intersection");
writer.WriteStartArray();
writer.WriteRule(value.Set1, options);
writer.WriteRule(value.Set2, options);
writer.WriteEndArray();
writer.WriteEndObject();
}
}
98 changes: 98 additions & 0 deletions PBIXInspectorLibrary/CustomRules/SetSymmetricDifferenceRule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using Json.Logic;
using Json.More;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;


namespace PBIXInspectorLibrary.CustomRules;

/// <summary>
/// Handles the `symdiff` operation.
/// </summary>
[Operator("symdiff")]
[JsonConverter(typeof(SetSymmetricDifferenceRuleJsonConverter))]
public class SetSymmetricDifferenceRule : Json.Logic.Rule
{
internal Json.Logic.Rule Set1 { get; }
internal Json.Logic.Rule Set2 { get; }

public SetSymmetricDifferenceRule(Json.Logic.Rule set1, Json.Logic.Rule set2)
{
Set1 = set1;
Set2 = set2;
}

/// <summary>
/// Applies the rule to the input data.
/// </summary>
/// <param name="data">The input data.</param>
/// <param name="contextData">
/// Optional secondary data. Used by a few operators to pass a secondary
/// data context to inner operators.
/// </param>
/// <returns>The result of the rule.</returns>
public override JsonNode? Apply(JsonNode? data, JsonNode? contextData = null)
{
var set1 = Set1.Apply(data, contextData);
var set2 = Set2.Apply(data, contextData);

if (set1 is not JsonArray || set2 is not JsonArray)
return new JsonArray();

var arr1 = (JsonArray)set1;
var arr2 = (JsonArray)set2;

var symmetricDifference = new JsonArray();

foreach (var item in arr1)
{
if (!arr2.Any(x => item.IsEquivalentTo(x)))
{
var copy = item.Copy();
if (!symmetricDifference.Any(x => x.IsEquivalentTo(copy)))
{
symmetricDifference.Add(copy);
}
}
}

foreach (var item in arr2)
{
if (!arr1.Any(x => item.IsEquivalentTo(x)))
{
var copy = item.Copy();
if (!symmetricDifference.Any(x => x.IsEquivalentTo(copy)))
{
symmetricDifference.Add(copy);
}
}
}

return symmetricDifference;
}
}

internal class SetSymmetricDifferenceRuleJsonConverter : JsonConverter<SetSymmetricDifferenceRule>
{
public override SetSymmetricDifferenceRule? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var parameters = JsonSerializer.Deserialize<Json.Logic.Rule[]>(ref reader, options);

if (parameters is not { Length: 2 })
throw new JsonException("The symdiff rule needs an array with 2 parameters.");

return new SetSymmetricDifferenceRule(parameters[0], parameters[1]);
}

public override void Write(Utf8JsonWriter writer, SetSymmetricDifferenceRule value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WritePropertyName("symdiff");
writer.WriteStartArray();
writer.WriteRule(value.Set1, options);
writer.WriteRule(value.Set2, options);
writer.WriteEndArray();
writer.WriteEndObject();
}
}
Loading

0 comments on commit d6dd501

Please sign in to comment.