1local stanza = require"util.stanza".stanza;
2local tostring, tonumber = tostring, tonumber;
3local type = type;
4local pairs = pairs;
5
6local xmlns_rsm = 'http://jabber.org/protocol/rsm';
7
8local element_parsers = {};
9
10do
11	local parsers = element_parsers;
12	local function xs_int(st)
13		return tonumber((st:get_text()));
14	end
15	local function xs_string(st)
16		return st:get_text();
17	end
18
19	parsers.after = xs_string;
20	parsers.before = function(st)
21			local text = st:get_text();
22			return text == "" or text;
23		end;
24	parsers.max = xs_int;
25	parsers.index = xs_int;
26
27	parsers.first = function(st)
28			return { index = tonumber(st.attr.index); st:get_text() };
29		end;
30	parsers.last = xs_string;
31	parsers.count = xs_int;
32end
33
34local element_generators = setmetatable({
35	first = function(st, data)
36		if type(data) == "table" then
37			st:tag("first", { index = data.index }):text(data[1]):up();
38		else
39			st:tag("first"):text(tostring(data)):up();
40		end
41	end;
42	before = function(st, data)
43		if data == true then
44			st:tag("before"):up();
45		else
46			st:tag("before"):text(tostring(data)):up();
47		end
48	end
49}, {
50	__index = function(_, name)
51		return function(st, data)
52			st:tag(name):text(tostring(data)):up();
53		end
54	end;
55});
56
57
58local function parse(set)
59	local rs = {};
60	for tag in set:childtags() do
61		local name = tag.name;
62		local parser = name and element_parsers[name];
63		if parser then
64			rs[name] = parser(tag);
65		end
66	end
67	return rs;
68end
69
70local function generate(t)
71	local st = stanza("set", { xmlns = xmlns_rsm });
72	for k,v in pairs(t) do
73		if element_parsers[k] then
74			element_generators[k](st, v);
75		end
76	end
77	return st;
78end
79
80local function get(st)
81	local set = st:get_child("set", xmlns_rsm);
82	if set and #set.tags > 0 then
83		return parse(set);
84	end
85end
86
87return { parse = parse, generate = generate, get = get };
88