// Copyright © WireMock.Net using System; using System.Linq; using System.Linq.Dynamic.Core; using AnyOfTypes; using Newtonsoft.Json.Linq; using Stef.Validation; using WireMock.Extensions; using WireMock.Json; using WireMock.Models; using WireMock.Util; namespace WireMock.Matchers; /// /// System.Linq.Dynamic.Core Expression Matcher /// /// /// public class LinqMatcher : IObjectMatcher, IStringMatcher { private readonly AnyOf[] _patterns; /// public MatchBehaviour MatchBehaviour { get; } /// public object Value { get; } /// /// Initializes a new instance of the class. /// /// The pattern. public LinqMatcher(AnyOf pattern) : this(new[] { pattern }) { } /// /// Initializes a new instance of the class. /// /// The patterns. public LinqMatcher(params AnyOf[] patterns) : this(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, patterns) { } /// /// Initializes a new instance of the class. /// /// The match behaviour. /// The pattern. public LinqMatcher(MatchBehaviour matchBehaviour, AnyOf pattern) : this(matchBehaviour, MatchOperator.Or, pattern) { } /// /// Initializes a new instance of the class. /// /// The match behaviour. /// The to use. (default = "Or") /// The patterns. public LinqMatcher( MatchBehaviour matchBehaviour, MatchOperator matchOperator = MatchOperator.Or, params AnyOf[] patterns) { _patterns = Guard.NotNull(patterns); MatchBehaviour = matchBehaviour; MatchOperator = matchOperator; Value = patterns; } /// public MatchResult IsMatch(string? input) { var score = MatchScores.Mismatch; Exception? error = null; // Convert a single input string to a Queryable string-list with 1 entry. IQueryable queryable = new[] { input }.AsQueryable(); try { // Use the Any(...) method to check if the result matches score = MatchScores.ToScore(_patterns.Select(pattern => queryable.Any(pattern.GetPattern())).ToArray(), MatchOperator); } catch (Exception e) { error = e; } return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), error); } /// public MatchResult IsMatch(object? input) { var score = MatchScores.Mismatch; Exception? error = null; JArray jArray; try { jArray = new JArray { input }; } catch { jArray = input == null ? new JArray() : new JArray { JToken.FromObject(input) }; } // Convert a single object to a Queryable JObject-list with 1 entry. var queryable = jArray.ToDynamicClassArray().AsQueryable(); try { var patternsAsStringArray = _patterns.Select(p => p.GetPattern()).ToArray(); var scores = patternsAsStringArray.Select(p => queryable.Any(p)).ToArray(); score = MatchScores.ToScore(scores, MatchOperator); } catch (Exception e) { error = e; } return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), error); } /// public AnyOf[] GetPatterns() { return _patterns; } /// public MatchOperator MatchOperator { get; } /// public string Name => nameof(LinqMatcher); /// public string GetCSharpCodeArguments() { return $"new {Name}" + $"(" + $"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " + $"{MatchOperator.GetFullyQualifiedEnumValue()}, " + $"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}" + $")"; } }