|
1 local stanza = require"util.stanza".stanza; |
|
2 local tostring, tonumber = tostring, tonumber; |
|
3 local type = type; |
|
4 local pairs = pairs; |
|
5 |
|
6 local xmlns_rsm = 'http://jabber.org/protocol/rsm'; |
|
7 |
|
8 local element_parsers = {}; |
|
9 |
|
10 do |
|
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; |
|
32 end |
|
33 |
|
34 local 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 |
|
58 local 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; |
|
68 end |
|
69 |
|
70 local 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; |
|
78 end |
|
79 |
|
80 local 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 |
|
85 end |
|
86 |
|
87 return { parse = parse, generate = generate, get = get }; |