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