public Task <AppUser?> TryGet([FromRoute] long id, CancellationToken cancellationToken = default)
 => AppUsers.TryGet(id, cancellationToken);
Exemple #2
0
        public virtual async Task <GameMessage> Parse(string text, CancellationToken cancellationToken = default)
        {
            List <MessageFragment> fragments = new();
            var startIndex = 0;

            void AddPlainText(int length)
            {
                if (length < 0)
                {
                    startIndex -= length;
                }
                fragments.Add(new PlainText(text.Substring(startIndex, length)));
                startIndex += length;
            }

            bool StartsWith(string start) => text.AsSpan(startIndex).StartsWith(start);

            bool TryParseDirective(string directive, out string value)
            {
                value = "";
                if (!StartsWith(directive))
                {
                    return(false);
                }
                if (startIndex + directive.Length + 2 >= text.Length || text[startIndex + directive.Length] != '[')
                {
                    AddPlainText(directive.Length);
                    return(false);
                }
                var valueStartIndex   = startIndex + directive.Length + 1;
                var rightBracketIndex = text.IndexOf(']', valueStartIndex);

                if (rightBracketIndex < 0)
                {
                    AddPlainText(directive.Length);
                    return(false);
                }
                value      = text.Substring(valueStartIndex, rightBracketIndex - valueStartIndex);
                startIndex = rightBracketIndex + 1;
                return(true);
            }

            while (startIndex < text.Length)
            {
                if (text[startIndex] != '@')
                {
                    var endIndex = text.IndexOf('@', startIndex);
                    if (endIndex < 0)
                    {
                        endIndex = text.Length;
                    }
                    AddPlainText(endIndex - startIndex);
                    continue;
                }
                if (StartsWith("@@"))
                {
                    fragments.Add(new PlainText("@"));
                    startIndex += 2;
                    continue;
                }

                var directiveStartIndex = startIndex;
                if (TryParseDirective("@user", out var userIdText))
                {
                    if (!long.TryParse(userIdText, out var userId))
                    {
                        AddPlainText(directiveStartIndex - startIndex);
                        continue;
                    }
                    var user = await AppUsers.TryGet(userId, cancellationToken);

                    if (user == null)
                    {
                        AddPlainText(directiveStartIndex - startIndex);
                        continue;
                    }
                    fragments.Add(new UserMention(user));
                    continue;
                }
                if (TryParseDirective("@score", out var scoreText))
                {
                    var scoreParts = scoreText.Split(",");
                    if (scoreParts.Length != 2)
                    {
                        AddPlainText(directiveStartIndex - startIndex);
                        continue;
                    }
                    var gameId = scoreParts[0].Trim();
                    if (string.IsNullOrEmpty(gameId))
                    {
                        AddPlainText(directiveStartIndex - startIndex);
                        continue;
                    }
                    if (!long.TryParse(scoreParts[1].Trim(), out var score))
                    {
                        AddPlainText(directiveStartIndex - startIndex);
                        continue;
                    }
                    var game = await Games.TryGet(gameId, cancellationToken);

                    if (game == null)
                    {
                        AddPlainText(directiveStartIndex - startIndex);
                        continue;
                    }
                    fragments.Add(new GameScoreMention(game, score));
                    continue;
                }
                if (StartsWith("@"))
                {
                    var name = UserNameService.ParseName(text, startIndex + 1);
                    if (string.IsNullOrEmpty(name))
                    {
                        AddPlainText(1);
                        continue;
                    }
                    var user = await AppUsers.TryGetByName(name, cancellationToken);

                    if (user == null)
                    {
                        AddPlainText(name.Length + 1);
                        continue;
                    }
                    fragments.Add(new UserMention(user));
                    startIndex += name.Length + 1;
                    continue;
                }
            }

            List <MessageFragment> optimizedFragments = new();
            MessageFragment?       lastFragment       = null;

            foreach (var fragment in fragments)
            {
                if (fragment is PlainText pt && lastFragment is PlainText lpt)
                {
                    lastFragment = new PlainText(lpt.Text + pt.Text);
                    optimizedFragments.RemoveAt(optimizedFragments.Count - 1);
                }