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);
                    }
                }
            }
        }
Exemplo n.º 2
0
        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);
        }