aboutsummaryrefslogtreecommitdiffstats
path: root/util/rsm.lua
blob: aade3c19af95859fac833cc79f0a943704fca5c2 (plain)
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
-- Prosody IM
-- Copyright (C) 2008-2017 Matthew Wild
-- Copyright (C) 2008-2017 Waqas Hussain
-- Copyright (C) 2011-2017 Kim Alvefur
--
-- This project is MIT/X11 licensed. Please see the
-- COPYING file in the source package for more information.
--
-- XEP-0313: Message Archive Management for Prosody
--

local stanza = require"util.stanza".stanza;
local tostring, tonumber = tostring, tonumber;
local s_format = string.format;
local type = type;
local pairs = pairs;

local function inttostr(n)
	return s_format("%d", n);
end

local xmlns_rsm = 'http://jabber.org/protocol/rsm';

local element_parsers = {};

do
	local parsers = element_parsers;
	local function xs_int(st)
		return tonumber((st:get_text()));
	end
	local function xs_string(st)
		return st:get_text();
	end

	parsers.after = xs_string;
	parsers.before = function(st)
			local text = st:get_text();
			return text == "" or text;
		end;
	parsers.max = xs_int;
	parsers.index = xs_int;

	parsers.first = function(st)
			return { index = tonumber(st.attr.index); st:get_text() };
		end;
	parsers.last = xs_string;
	parsers.count = xs_int;
end

local element_generators = setmetatable({
	first = function(st, data)
		if type(data) == "table" then
			st:tag("first", { index = inttostr(data.index) }):text(data[1]):up();
		else
			st:tag("first"):text(tostring(data)):up();
		end
	end;
	before = function(st, data)
		if data == true then
			st:tag("before"):up();
		else
			st:tag("before"):text(tostring(data)):up();
		end
	end;
	max = function (st, data)
		st:tag("max"):text(inttostr(data)):up();
	end;
	count = function (st, data)
		st:tag("count"):text(inttostr(data)):up();
	end;
}, {
	__index = function(_, name)
		return function(st, data)
			st:tag(name):text(tostring(data)):up();
		end
	end;
});


local function parse(set)
	local rs = {};
	for tag in set:childtags() do
		local name = tag.name;
		local parser = name and element_parsers[name];
		if parser then
			rs[name] = parser(tag);
		end
	end
	return rs;
end

local function generate(t)
	local st = stanza("set", { xmlns = xmlns_rsm });
	for k,v in pairs(t) do
		if element_parsers[k] then
			element_generators[k](st, v);
		end
	end
	return st;
end

local function get(st)
	local set = st:get_child("set", xmlns_rsm);
	if set and #set.tags > 0 then
		return parse(set);
	end
end

return { parse = parse, generate = generate, get = get };