summaryrefslogtreecommitdiff
path: root/src/types/MessageEntity.zig
blob: 1c44d207e56102d7cf5bedd0a3a26dc02350f6d0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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..];
}