Files
speckle-sharp-sdk/src/Speckle.Core/Models/GraphTraversal/RuleBuilder.cs
T
Adam Hathcock 200b84f49a Main to dev (#18)
* 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>
2024-07-09 13:56:03 +01:00

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);
}