protected virtual IEnumerable <(QueryToken token, ImmutableStack <OmniboxMatch> stack)> GetAmbiguousTokens(QueryToken?queryToken, ImmutableStack <OmniboxMatch> distancePack, QueryDescription queryDescription, List <OmniboxToken> omniboxTokens, int index, int operatorIndex) { OmniboxToken omniboxToken = omniboxTokens[index]; bool isPascal = OmniboxUtils.IsPascalCasePattern(omniboxToken.Value); var dic = QueryUtils.SubTokens(queryToken, queryDescription, SubTokensOptions.CanAnyAll | SubTokensOptions.CanElement).ToOmniboxPascalDictionary(qt => qt.ToString(), qt => qt); var matches = OmniboxUtils.Matches(dic, qt => qt.IsAllowed() == null, omniboxToken.Value, isPascal); if (index == operatorIndex - 1) { foreach (var m in matches) { var token = (QueryToken)m.Value; yield return(token : token, stack : distancePack.Push(m)); } } else { foreach (var m in matches) { foreach (var newPair in GetAmbiguousTokens((QueryToken)m.Value, distancePack.Push(m), queryDescription, omniboxTokens, index + 2, operatorIndex)) { yield return(newPair); } } } }
protected virtual ValueTuple[] GetValues(QueryToken queryToken, OmniboxToken omniboxToken) { if (omniboxToken.IsNull()) { return new[] { new ValueTuple { Value = null, Match = null } } } ; var ft = QueryUtils.GetFilterType(queryToken.Type); switch (ft) { case FilterType.Integer: case FilterType.Decimal: if (omniboxToken.Type == OmniboxTokenType.Number) { if (ReflectionTools.TryParse(omniboxToken.Value, queryToken.Type, out object?result)) { return new[] { new ValueTuple { Value = result, Match = null } } } ; } break; case FilterType.String: if (omniboxToken.Type == OmniboxTokenType.String) { return new[] { new ValueTuple { Value = OmniboxUtils.CleanCommas(omniboxToken.Value), Match = null } } } ; break; case FilterType.DateTime: if (omniboxToken.Type == OmniboxTokenType.String) { var str = OmniboxUtils.CleanCommas(omniboxToken.Value); if (ReflectionTools.TryParse(str, queryToken.Type, out object?result)) { return new[] { new ValueTuple { Value = result, Match = null } } } ; } break; case FilterType.Lite: if (omniboxToken.Type == OmniboxTokenType.String) { var patten = OmniboxUtils.CleanCommas(omniboxToken.Value); var result = OmniboxParser.Manager.Autocomplete(queryToken.GetImplementations() !.Value, patten, AutoCompleteLimit); return(result.Select(lite => new ValueTuple { Value = lite, Match = OmniboxUtils.Contains(lite, lite.ToString() !, patten) }).ToArray()); } else if (omniboxToken.Type == OmniboxTokenType.Entity) { var error = Lite.TryParseLite(omniboxToken.Value, out Lite <Entity>?lite); if (string.IsNullOrEmpty(error)) { return new [] { new ValueTuple { Value = lite } } } ; } else if (omniboxToken.Type == OmniboxTokenType.Number) { var imp = queryToken.GetImplementations() !.Value; if (!imp.IsByAll) { return(imp.Types.Select(t => CreateLite(t, omniboxToken.Value)) .NotNull().Select(t => new ValueTuple { Value = t }).ToArray()); } } break;
protected virtual ValueTuple[] GetValues(QueryToken queryToken, OmniboxToken omniboxToken) { if (omniboxToken.IsNull()) { return new[] { new ValueTuple { Value = null, Match = null } } } ; var ft = QueryUtils.GetFilterType(queryToken.Type); switch (ft) { case FilterType.Integer: case FilterType.Decimal: if (omniboxToken.Type == OmniboxTokenType.Number) { if (ReflectionTools.TryParse(omniboxToken.Value, queryToken.Type, out object?result)) { return new[] { new ValueTuple { Value = result, Match = null } } } ; } break; case FilterType.String: if (omniboxToken.Type == OmniboxTokenType.String) { return new[] { new ValueTuple { Value = OmniboxUtils.CleanCommas(omniboxToken.Value), Match = null } } } ; break; case FilterType.DateTime: if (omniboxToken.Type == OmniboxTokenType.String) { var str = OmniboxUtils.CleanCommas(omniboxToken.Value); if (ReflectionTools.TryParse(str, queryToken.Type, out object?result)) { return new[] { new ValueTuple { Value = result, Match = null } } } ; } break; case FilterType.Lite: if (omniboxToken.Type == OmniboxTokenType.String) { var patten = OmniboxUtils.CleanCommas(omniboxToken.Value); var result = OmniboxParser.Manager.Autocomplete(queryToken.GetImplementations() !.Value, patten, AutoCompleteLimit); return(result.Select(lite => new ValueTuple { Value = lite, Match = OmniboxUtils.Contains(lite, lite.ToString(), patten) }).ToArray()); } else if (omniboxToken.Type == OmniboxTokenType.Entity) { var error = Lite.TryParseLite(omniboxToken.Value, out Lite <Entity>?lite); if (string.IsNullOrEmpty(error)) { return new [] { new ValueTuple { Value = lite } } } ; } else if (omniboxToken.Type == OmniboxTokenType.Number) { var imp = queryToken.GetImplementations() !.Value; if (!imp.IsByAll) { return(imp.Types.Select(t => CreateLite(t, omniboxToken.Value)) .NotNull().Select(t => new ValueTuple { Value = t }).ToArray()); } } break; case FilterType.Embedded: case FilterType.Boolean: bool?boolean = ParseBool(omniboxToken.Value); if (boolean.HasValue) { return new [] { new ValueTuple { Value = boolean.Value } } } ; break; case FilterType.Enum: if (omniboxToken.Type == OmniboxTokenType.String || omniboxToken.Type == OmniboxTokenType.Identifier) { string value = omniboxToken.Type == OmniboxTokenType.Identifier ? omniboxToken.Value : OmniboxUtils.CleanCommas(omniboxToken.Value); bool isPascalValue = OmniboxUtils.IsPascalCasePattern(value); Type enumType = queryToken.Type.UnNullify(); var dic = EnumEntity.GetValues(enumType).ToOmniboxPascalDictionary(a => a.NiceToString(), a => (object)a); var result = OmniboxUtils.Matches(dic, e => true, value, isPascalValue) .Select(m => new ValueTuple { Value = m.Value, Match = m }) .ToArray(); return(result); } break; case FilterType.Guid: if (omniboxToken.Type == OmniboxTokenType.Guid) { if (Guid.TryParse(omniboxToken.Value, out Guid result)) { return new[] { new ValueTuple { Value = result, Match = null } } } ; } else if (omniboxToken.Type == OmniboxTokenType.String) { var str = OmniboxUtils.CleanCommas(omniboxToken.Value); if (Guid.TryParse(str, out Guid result)) { return new[] { new ValueTuple { Value = result, Match = null } } } ; } break; default: break; } return(new[] { new ValueTuple { Value = UnknownValue, Match = null } }); } Lite <Entity>?CreateLite(Type type, string value) { if (PrimaryKey.TryParse(value, type, out PrimaryKey id)) { return(Lite.Create(type, id, "{0} {1}".FormatWith(type.NiceName(), id))); } return(null); } bool?ParseBool(string val) { val = val.ToLower().RemoveDiacritics(); if (val == "true" || val == "t" || val == "yes" || val == "y" || val == OmniboxMessage.Yes.NiceToString()) { return(true); } if (val == "false" || val == "f" || val == "no" || val == "n" || val == OmniboxMessage.No.NiceToString()) { return(false); } return(null); }