const std = @import("std"); const MessageEntity = @This(); const User = @import("User.zig"); const Utf8View = std.unicode.Utf8View; pub const Type = enum { mention, hashtag, cashtag, bot_command, url, email, phone_number, bold, italic, underline, strikethrough, spoiler, blockquote, expandable_blockquote, code, pre, text_link, text_mention, custom_emoji, }; type: Type, offset: u64, length: u64, url: ?[]const u8 = null, user: ?User = null, language: ?[]const u8 = null, custom_emoji_id: ?[]const u8 = null, pub fn extract(self: MessageEntity, src: []const u8) ![]const u8 { if (self.length == 0) { return ""; } var utf8 = (try Utf8View.init(src)).iterator(); var i: usize = 0; const start = if (i >= self.offset) utf8.i else blk: { while (utf8.nextCodepoint()) |cp| { i += std.unicode.utf16CodepointSequenceLength(cp) catch unreachable; if (i >= self.offset) { break :blk utf8.i; } } return ""; }; i = 0; while (utf8.nextCodepoint()) |cp| { i += std.unicode.utf16CodepointSequenceLength(cp) catch unreachable; if (i >= self.length) { return src[start..utf8.i]; } } return src[start..]; }