// Copyright © WireMock.Net using System.Linq; using AnyOfTypes; using SimMetrics.Net; using SimMetrics.Net.API; using SimMetrics.Net.Metric; using Stef.Validation; using WireMock.Extensions; using WireMock.Models; using WireMock.Util; namespace WireMock.Matchers; /// /// SimMetricsMatcher /// /// public class SimMetricsMatcher : IStringMatcher { private readonly AnyOf[] _patterns; private readonly SimMetricType _simMetricType; /// public MatchBehaviour MatchBehaviour { get; } /// /// Initializes a new instance of the class. /// /// The pattern. /// The SimMetric Type public SimMetricsMatcher(AnyOf pattern, SimMetricType simMetricType = SimMetricType.Levenstein) : this(new[] { pattern }, simMetricType) { } /// /// Initializes a new instance of the class. /// /// The match behaviour. /// The pattern. /// The SimMetric Type public SimMetricsMatcher(MatchBehaviour matchBehaviour, AnyOf pattern, SimMetricType simMetricType = SimMetricType.Levenstein) : this(matchBehaviour, new[] { pattern }, simMetricType) { } /// /// Initializes a new instance of the class. /// /// The patterns. /// The SimMetric Type public SimMetricsMatcher(string[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein) : this(MatchBehaviour.AcceptOnMatch, patterns.ToAnyOfPatterns(), simMetricType) { } /// /// Initializes a new instance of the class. /// /// The patterns. /// The SimMetric Type public SimMetricsMatcher(AnyOf[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein) : this(MatchBehaviour.AcceptOnMatch, patterns, simMetricType) { } /// /// Initializes a new instance of the class. /// /// The match behaviour. /// The patterns. /// The SimMetric Type /// The to use. (default = "Or") public SimMetricsMatcher( MatchBehaviour matchBehaviour, AnyOf[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein, MatchOperator matchOperator = MatchOperator.Average) { _patterns = Guard.NotNull(patterns); _simMetricType = simMetricType; MatchBehaviour = matchBehaviour; MatchOperator = matchOperator; } /// public MatchResult IsMatch(string? input) { IStringMetric stringMetricType = GetStringMetricType(); var score = MatchScores.ToScore(_patterns.Select(p => stringMetricType.GetSimilarity(p.GetPattern(), input)).ToArray(), MatchOperator); return MatchBehaviourHelper.Convert(MatchBehaviour, score); } /// public virtual string GetCSharpCodeArguments() { return $"new {Name}" + $"(" + $"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " + $"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " + $"{_simMetricType.GetFullyQualifiedEnumValue()}, " + $"{MatchOperator.GetFullyQualifiedEnumValue()}" + $")"; } private IStringMetric GetStringMetricType() { return _simMetricType switch { SimMetricType.BlockDistance => new BlockDistance(), SimMetricType.ChapmanLengthDeviation => new ChapmanLengthDeviation(), SimMetricType.CosineSimilarity => new CosineSimilarity(), SimMetricType.DiceSimilarity => new DiceSimilarity(), SimMetricType.EuclideanDistance => new EuclideanDistance(), SimMetricType.JaccardSimilarity => new JaccardSimilarity(), SimMetricType.Jaro => new Jaro(), SimMetricType.JaroWinkler => new JaroWinkler(), SimMetricType.MatchingCoefficient => new MatchingCoefficient(), SimMetricType.MongeElkan => new MongeElkan(), SimMetricType.NeedlemanWunch => new NeedlemanWunch(), SimMetricType.OverlapCoefficient => new OverlapCoefficient(), SimMetricType.QGramsDistance => new QGramsDistance(), SimMetricType.SmithWaterman => new SmithWaterman(), SimMetricType.SmithWatermanGotoh => new SmithWatermanGotoh(), SimMetricType.SmithWatermanGotohWindowedAffine => new SmithWatermanGotohWindowedAffine(), SimMetricType.ChapmanMeanLength => new ChapmanMeanLength(), _ => new Levenstein() }; } /// public AnyOf[] GetPatterns() { return _patterns; } /// public MatchOperator MatchOperator { get; } = MatchOperator.Average; /// public string Name => $"SimMetricsMatcher.{_simMetricType}"; }