200b84f49a
* Add Instances base (#6) * Use Uri for checks in GetAccounts function (#8) * Add integration and perf tests to sln (#9) * Remove perf tests (#10) * remove perf tests * do all unit tests * Code coverage (#11) * code coverage * enable codecov for GA * Update README.md * Update coverage and dependencies (#12) * Update coverage and dependencies * fmt * add codecov config * merge DUI3/Alpha into sdk (#13) * merge DUI3/Alpha into sdk * formatting * Merge Objects dui3/alpha -> dev (#14) * merge DUI3/Alpha into sdk * formatting * Objects changes * Objects tests * Unit test project * update codecov to be less intrusive (#15) * update codecov to be less intrusive * fix codecov yaml * add coverage exclusion * Merge sharp `dui3/alpha` -> sdk `main` (#16) * Merge * csharpier format * Fixed polysharp issues * Integration Tests * Fixes * Some nullability fixes (#17) * add coverage exclusion * fix some tests and fix nullability errors --------- Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com> Co-authored-by: Jedd Morgan <45512892+JR-Morgan@users.noreply.github.com>
107 lines
3.5 KiB
C#
107 lines
3.5 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Speckle.Core.Common;
|
|
|
|
namespace Speckle.Core.Models.GraphTraversal;
|
|
|
|
/// <summary>
|
|
/// A traversal rule defines the conditional traversal behaviour when traversing a given <see cref="Base"/> objects.
|
|
/// Specifies what members to traverse if any provided <see cref="_conditions"/> are met.
|
|
/// </summary>
|
|
/// <remarks>Follows the builder pattern to ensure that a rule is complete before usable, see usages</remarks>
|
|
public sealed class TraversalRule : ITraversalBuilderReturn, ITraversalBuilderTraverse
|
|
{
|
|
private readonly List<WhenCondition> _conditions;
|
|
private SelectMembers? _membersToTraverse;
|
|
public bool ShouldReturn { get; private set; } = true;
|
|
|
|
private TraversalRule()
|
|
{
|
|
_conditions = new List<WhenCondition>();
|
|
}
|
|
|
|
public ITraversalBuilderReturn ContinueTraversing(SelectMembers membersToTraverse)
|
|
{
|
|
this._membersToTraverse = membersToTraverse;
|
|
return this;
|
|
}
|
|
|
|
public ITraversalRule ShouldReturnToOutput(bool shouldReturn = true)
|
|
{
|
|
ShouldReturn = shouldReturn;
|
|
return this;
|
|
}
|
|
|
|
public ITraversalBuilderTraverse When(WhenCondition condition)
|
|
{
|
|
_conditions.Add(condition);
|
|
return this;
|
|
}
|
|
|
|
bool ITraversalRule.DoesRuleHold(Base o)
|
|
{
|
|
foreach (var condition in _conditions)
|
|
{
|
|
if (condition.Invoke(o))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
IEnumerable<string> ITraversalRule.MembersToTraverse(Base o)
|
|
{
|
|
return _membersToTraverse.NotNull()(o).Distinct(); //TODO distinct is expensive, there may be a better way for us to avoid duplicates
|
|
}
|
|
|
|
/// <returns>a new Traversal Rule to be initialised using the Builder Pattern interfaces</returns>
|
|
public static ITraversalBuilderWhen NewTraversalRule()
|
|
{
|
|
return new TraversalRule();
|
|
}
|
|
}
|
|
|
|
public delegate bool WhenCondition(Base o);
|
|
|
|
/// <summary>
|
|
/// Builder Pattern Interface for a traversal rule in a partially built (unusable state)
|
|
/// </summary>
|
|
public interface ITraversalBuilderWhen
|
|
{
|
|
/// <summary>
|
|
/// Adds a condition to this rule. This rule will hold true when ANY of its conditions holds true.
|
|
/// </summary>
|
|
/// <param name="condition"></param>
|
|
/// <returns>Traversal rule in a building (unusable) state</returns>
|
|
ITraversalBuilderTraverse When(WhenCondition condition);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Delegate for selecting members (by member name) of an given <see cref="Base"/> object
|
|
/// </summary>
|
|
public delegate IEnumerable<string> SelectMembers(Base o);
|
|
|
|
/// <summary>
|
|
/// Builder Pattern Interface for a traversal rule in a partially built (unusable state)
|
|
/// </summary>
|
|
public interface ITraversalBuilderTraverse : ITraversalBuilderWhen
|
|
{
|
|
/// <seealso cref="ITraversalRule.MembersToTraverse"/>
|
|
/// <param name="membersToTraverse">Function returning the members that should be traversed for objects where this rule holds <see langword = "true"/></param>
|
|
/// <returns>Traversal rule in a usable state</returns>
|
|
ITraversalBuilderReturn ContinueTraversing(SelectMembers membersToTraverse);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Builder Pattern Interface for a traversal rule in a usable state, with an (optional) final step to set the value of <see cref="ITraversalRule.ShouldReturn"/>
|
|
/// </summary>
|
|
public interface ITraversalBuilderReturn : ITraversalRule
|
|
{
|
|
/// <seealso cref="ITraversalRule.MembersToTraverse"/>
|
|
/// <param name="shouldReturn">value to set <see cref="ITraversalRule.ShouldReturn"/></param>
|
|
/// <returns>Traversal rule in a usable state</returns>
|
|
ITraversalRule ShouldReturnToOutput(bool shouldReturn = true);
|
|
}
|