+ private List<Message.Mention> parseMentions(
+ final String selfNumber, final List<String> mentionStrings
+ ) throws UserErrorException {
+ final var mentionPattern = Pattern.compile("(\\d+):(\\d+):(.+)");
+ final var mentions = new ArrayList<Message.Mention>();
+ for (final var mention : mentionStrings) {
+ final var matcher = mentionPattern.matcher(mention);
+ if (!matcher.matches()) {
+ throw new UserErrorException("Invalid mention syntax ("
+ + mention
+ + ") expected 'start:length:recipientNumber'");
+ }
+ mentions.add(new Message.Mention(CommandUtil.getSingleRecipientIdentifier(matcher.group(3), selfNumber),
+ Integer.parseInt(matcher.group(1)),
+ Integer.parseInt(matcher.group(2))));
+ }
+ return mentions;
+ }
+
+ private List<TextStyle> parseTextStyles(
+ final List<String> textStylesStrings
+ ) throws UserErrorException {
+ final var textStylePattern = Pattern.compile("(\\d+):(\\d+):(.+)");
+ final var textStyles = new ArrayList<TextStyle>();
+ for (final var textStyle : textStylesStrings) {
+ final var matcher = textStylePattern.matcher(textStyle);
+ if (!matcher.matches()) {
+ throw new UserErrorException("Invalid textStyle syntax ("
+ + textStyle
+ + ") expected 'start:length:STYLE'");
+ }
+ final var style = TextStyle.Style.from(matcher.group(3));
+ if (style == null) {
+ throw new UserErrorException("Invalid style: " + matcher.group(3));
+ }
+ textStyles.add(new TextStyle(style,
+ Integer.parseInt(matcher.group(1)),
+ Integer.parseInt(matcher.group(2))));
+ }
+ return textStyles;
+ }
+
+ private Message.Sticker parseSticker(final String stickerString) throws UserErrorException {
+ final var stickerPattern = Pattern.compile("([\\da-f]+):(\\d+)");
+ final var matcher = stickerPattern.matcher(stickerString);
+ if (!matcher.matches() || matcher.group(1).length() % 2 != 0) {
+ throw new UserErrorException("Invalid sticker syntax ("
+ + stickerString
+ + ") expected 'stickerPackId:stickerId'");
+ }
+ return new Message.Sticker(Hex.toByteArray(matcher.group(1)), Integer.parseInt(matcher.group(2)));
+ }
+
+ private List<Message.Quote.Attachment> parseQuoteAttachments(
+ final List<String> attachmentStrings
+ ) throws UserErrorException {
+ final var attachmentPattern = Pattern.compile("([^:]+)(:([^:]+)(:(.+))?)?");
+ final var attachments = new ArrayList<Message.Quote.Attachment>();
+ for (final var attachment : attachmentStrings) {
+ final var matcher = attachmentPattern.matcher(attachment);
+ if (!matcher.matches()) {
+ throw new UserErrorException("Invalid attachment syntax ("
+ + attachment
+ + ") expected 'contentType[:filename[:previewFile]]'");
+ }
+ attachments.add(new Message.Quote.Attachment(matcher.group(1), matcher.group(3), matcher.group(5)));