aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--spec/util_datamapper_spec.lua8
-rw-r--r--teal-src/util/datamapper.tl43
-rw-r--r--util/datamapper.lua37
3 files changed, 63 insertions, 25 deletions
diff --git a/spec/util_datamapper_spec.lua b/spec/util_datamapper_spec.lua
index 3b0ae87e..51ccf127 100644
--- a/spec/util_datamapper_spec.lua
+++ b/spec/util_datamapper_spec.lua
@@ -25,7 +25,7 @@ describe("util.datamapper", function()
from = attr();
type = attr();
id = attr();
- body = "string";
+ body = true; -- should be assumed to be a string
lang = {type = "string"; xml = {attribute = true; prefix = "xml"}};
delay = {
type = "object";
@@ -56,7 +56,8 @@ describe("util.datamapper", function()
xml = {namespace = "urn:xmpp:reactions:0"; name = "reactions"};
properties = {
to = {type = "string"; xml = {attribute = true; name = "id"}};
- reactions = {type = "array"; items = {type = "string"; xml = {name = "reaction"}}};
+ -- should be assumed to be array since it has 'items'
+ reactions = { items = { xml = { name = "reaction" } } };
};
};
stanza_ids = {
@@ -190,7 +191,8 @@ describe("util.datamapper", function()
version = {
type = "object";
xml = {name = "query"; namespace = "jabber:iq:version"};
- properties = {name = "string"; version = "string"; os = "string"};
+ -- properties should be assumed to be strings
+ properties = {name = true; version = {}; os = {}};
};
};
};
diff --git a/teal-src/util/datamapper.tl b/teal-src/util/datamapper.tl
index 78ca3035..73b1dfc0 100644
--- a/teal-src/util/datamapper.tl
+++ b/teal-src/util/datamapper.tl
@@ -25,7 +25,7 @@ local pointer = require"util.jsonpointer";
local json_type_name = json.json_type_name;
local json_schema_object = require "util.jsonschema"
-local type schema_t = boolean | json_type_name | json_schema_object
+local type schema_t = boolean | json_schema_object
local function toboolean ( s : string ) : boolean
if s == "true" or s == "1" then
@@ -59,15 +59,28 @@ local enum value_goes
end
local function resolve_schema(schema : schema_t, root : json_schema_object) : schema_t
- if schema is json_schema_object and schema["$ref"] and schema["$ref"]:sub(1, 1) == "#" then
- local referenced = pointer.resolve(root as table, schema["$ref"]:sub(2)) as schema_t;
- if referenced ~= nil then
- return referenced
+ if schema is json_schema_object then
+ if schema["$ref"] and schema["$ref"]:sub(1, 1) == "#" then
+ return pointer.resolve(root as table, schema["$ref"]:sub(2)) as schema_t;
end
end
return schema;
end
+local function guess_schema_type(schema : json_schema_object) : json_type_name
+ local schema_types = schema.type
+ if schema_types is json_type_name then
+ return schema_types
+ elseif schema_types ~= nil then
+ error "schema has unsupported 'type' property"
+ elseif schema.properties then
+ return "object"
+ elseif schema.items then
+ return "array"
+ end
+ return "string" -- default assumption
+end
+
local function unpack_propschema( propschema : schema_t, propname : string, current_ns : string )
: json_type_name, value_goes, string, string, string, string, { any }
local proptype : json_type_name = "string"
@@ -79,9 +92,9 @@ local function unpack_propschema( propschema : schema_t, propname : string, curr
local enums : { any }
if propschema is json_schema_object then
- proptype = propschema.type
- elseif propschema is json_type_name then
- proptype = propschema
+ proptype = guess_schema_type(propschema);
+ elseif propschema is string then -- Teal says this can never be a string, but it could before so best be sure
+ error("schema as string is not supported: "..propschema.." {"..current_ns.."}"..propname)
end
if proptype == "object" or proptype == "array" then
@@ -120,6 +133,10 @@ local function unpack_propschema( propschema : schema_t, propname : string, curr
end
end
+ if current_ns == "urn:xmpp:reactions:0" and name == "reactions" then
+ assert(proptype=="array")
+ end
+
return proptype, value_where, name, namespace, prefix, single_attribute, enums
end
@@ -239,9 +256,10 @@ function parse_array (schema : json_schema_object, s : st.stanza_t, root : json_
end
local function parse (schema : json_schema_object, s : st.stanza_t) : table
- if schema.type == "object" then
+ local s_type = guess_schema_type(schema)
+ if s_type == "object" then
return parse_object(schema, s, schema)
- elseif schema.type == "array" then
+ elseif s_type == "array" then
return parse_array(schema, s, schema)
else
error "top-level scalars unsupported"
@@ -333,7 +351,8 @@ function unparse ( schema : json_schema_object, t : table, current_name : string
local out = ctx or st.stanza(current_name, { xmlns = current_ns })
- if schema.type == "object" then
+ local s_type = guess_schema_type(schema)
+ if s_type == "object" then
for prop, propschema in pairs(schema.properties) do
propschema = resolve_schema(propschema, root)
@@ -346,7 +365,7 @@ function unparse ( schema : json_schema_object, t : table, current_name : string
end
return out;
- elseif schema.type == "array" then
+ elseif s_type == "array" then
local itemschema = resolve_schema(schema.items, root)
local proptype, value_where, name, namespace, prefix, single_attribute = unpack_propschema(itemschema, current_name, current_ns)
for _, item in ipairs(t as { string }) do
diff --git a/util/datamapper.lua b/util/datamapper.lua
index 25c4c986..2378314c 100644
--- a/util/datamapper.lua
+++ b/util/datamapper.lua
@@ -1,3 +1,5 @@
+-- This file is generated from teal-src/util/datamapper.lua
+
local st = require("util.stanza");
local pointer = require("util.jsonpointer");
@@ -29,15 +31,28 @@ end
local value_goes = {}
local function resolve_schema(schema, root)
- if type(schema) == "table" and schema["$ref"] and schema["$ref"]:sub(1, 1) == "#" then
- local referenced = pointer.resolve(root, schema["$ref"]:sub(2));
- if referenced ~= nil then
- return referenced
+ if type(schema) == "table" then
+ if schema["$ref"] and schema["$ref"]:sub(1, 1) == "#" then
+ return pointer.resolve(root, schema["$ref"]:sub(2))
end
end
return schema
end
+local function guess_schema_type(schema)
+ local schema_types = schema.type
+ if type(schema_types) == "string" then
+ return schema_types
+ elseif schema_types ~= nil then
+ error("schema has unsupported 'type' property")
+ elseif schema.properties then
+ return "object"
+ elseif schema.items then
+ return "array"
+ end
+ return "string"
+end
+
local function unpack_propschema(propschema, propname, current_ns)
local proptype = "string"
@@ -49,9 +64,9 @@ local function unpack_propschema(propschema, propname, current_ns)
local enums
if type(propschema) == "table" then
- proptype = propschema.type
+ proptype = guess_schema_type(propschema);
elseif type(propschema) == "string" then
- proptype = propschema
+ error("schema as string is not supported: " .. propschema .. " {" .. current_ns .. "}" .. propname)
end
if proptype == "object" or proptype == "array" then
@@ -209,9 +224,10 @@ function parse_array(schema, s, root)
end
local function parse(schema, s)
- if schema.type == "object" then
+ local s_type = guess_schema_type(schema)
+ if s_type == "object" then
return parse_object(schema, s, schema)
- elseif schema.type == "array" then
+ elseif s_type == "array" then
return parse_array(schema, s, schema)
else
error("top-level scalars unsupported")
@@ -306,7 +322,8 @@ function unparse(schema, t, current_name, current_ns, ctx, root)
local out = ctx or st.stanza(current_name, {xmlns = current_ns})
- if schema.type == "object" then
+ local s_type = guess_schema_type(schema)
+ if s_type == "object" then
for prop, propschema in pairs(schema.properties) do
propschema = resolve_schema(propschema, root)
@@ -319,7 +336,7 @@ function unparse(schema, t, current_name, current_ns, ctx, root)
end
return out
- elseif schema.type == "array" then
+ elseif s_type == "array" then
local itemschema = resolve_schema(schema.items, root)
local proptype, value_where, name, namespace, prefix, single_attribute = unpack_propschema(itemschema, current_name, current_ns)
for _, item in ipairs(t) do