Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drillthrough jsonpointer in rules data mapping part. #24

Merged
merged 4 commits into from
Nov 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading