const std = @import("std"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayList; const CaseData = @import("CaseData"); const GenCatData = @import("GenCatData"); const Utf8View = std.unicode.Utf8View; pub fn escapeXml(writer: anytype, text: []const u8) !void { for (text) |ch| { try switch (ch) { '<' => writer.writeAll("<"), '>' => writer.writeAll(">"), '&' => writer.writeAll("&"), '"' => writer.writeAll("""), else => writer.writeByte(ch), }; } } var gcd_global: ?GenCatData = null; pub fn getGCD() !GenCatData { if (gcd_global) |gcd| { return gcd; } gcd_global = try GenCatData.init(std.heap.page_allocator); return gcd_global.?; } var cd_global: ?CaseData = null; pub fn getCD() !CaseData { if (cd_global) |cd| { return cd; } cd_global = try CaseData.init(std.heap.page_allocator); return cd_global.?; } pub inline fn isNull(value: anytype) bool { return switch (@typeInfo(@TypeOf(value))) { .Null => true, .Optional => value == null, else => false, }; } pub fn isTgWhitespaceStr(str: []const u8) !bool { const view = try Utf8View.init(str); const gcd = try getGCD(); var it = view.iterator(); while (it.nextCodepoint()) |cp| { if (!isTgWhitespace(gcd, cp)) { return false; } } return true; } inline fn isTgWhitespace(gcd: GenCatData, cp: u21) bool { return gcd.isSeparator(cp) or gcd.isControl(cp) or cp == 0x2800 // BRAILLE PATTERN BLANK, telegram treats messages with just this as invalid messages ; }