diff options
Diffstat (limited to 'teal-src/util')
31 files changed, 0 insertions, 1579 deletions
diff --git a/teal-src/util/compat.d.tl b/teal-src/util/compat.d.tl deleted file mode 100644 index da9c6083..00000000 --- a/teal-src/util/compat.d.tl +++ /dev/null @@ -1,4 +0,0 @@ -local record lib - xpcall : function (function, function, ...:any):boolean, any -end -return lib diff --git a/teal-src/util/crand.d.tl b/teal-src/util/crand.d.tl deleted file mode 100644 index b40cb67e..00000000 --- a/teal-src/util/crand.d.tl +++ /dev/null @@ -1,6 +0,0 @@ -local record lib - bytes : function (n : integer) : string - enum sourceid "OpenSSL" "arc4random()" "Linux" end - _source : sourceid -end -return lib diff --git a/teal-src/util/dataforms.d.tl b/teal-src/util/dataforms.d.tl deleted file mode 100644 index 9e4170fa..00000000 --- a/teal-src/util/dataforms.d.tl +++ /dev/null @@ -1,52 +0,0 @@ -local stanza_t = require "util.stanza".stanza_t - -local enum form_type - "form" - "submit" - "cancel" - "result" -end - -local enum field_type - "boolean" - "fixed" - "hidden" - "jid-multi" - "jid-single" - "list-multi" - "list-single" - "text-multi" - "text-private" - "text-single" -end - -local record form_field - - type : field_type - var : string -- protocol name - name : string -- internal name - - label : string - desc : string - - datatype : string - range_min : number - range_max : number - - value : any -- depends on field_type - options : table -end - -local record dataform - title : string - instructions : string - { form_field } -- XXX https://github.com/teal-language/tl/pull/415 - - form : function ( dataform, table, form_type ) : stanza_t -end - -local record lib - new : function ( dataform ) : dataform -end - -return lib diff --git a/teal-src/util/datamapper.tl b/teal-src/util/datamapper.tl deleted file mode 100644 index 73b1dfc0..00000000 --- a/teal-src/util/datamapper.tl +++ /dev/null @@ -1,381 +0,0 @@ --- Copyright (C) 2021 Kim Alvefur --- --- This project is MIT/X11 licensed. Please see the --- COPYING file in the source package for more information. --- --- Based on --- https://json-schema.org/draft/2020-12/json-schema-core.html --- https://json-schema.org/draft/2020-12/json-schema-validation.html --- http://spec.openapis.org/oas/v3.0.1#xmlObject --- https://github.com/OAI/OpenAPI-Specification/issues/630 (text:true) --- --- XML Object Extensions: --- text to refer to the text content at the same time as attributes --- x_name_is_value for enum fields where the <tag-name/> is the value --- x_single_attribute for <tag attr="this"/> --- --- TODO pointers --- TODO cleanup / refactor --- TODO s/number/integer/ once we have appropriate math.type() compat --- - -local st = require "util.stanza"; -local json = require"util.json" -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_schema_object - -local function toboolean ( s : string ) : boolean - if s == "true" or s == "1" then - return true - elseif s == "false" or s == "0" then - return false - elseif s then - return true - end -end - -local function totype(t : json_type_name, s : string) : any - if not s then return nil end - if t == "string" then - return s; - elseif t == "boolean" then - return toboolean(s) - elseif t == "number" or t == "integer" then - return tonumber(s) - end -end - -local enum value_goes - "in_tag_name" - "in_text" - "in_text_tag" - "in_attribute" - "in_single_attribute" - "in_children" - "in_wrapper" -end - -local function resolve_schema(schema : schema_t, root : json_schema_object) : schema_t - 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" - local value_where : value_goes = propname and "in_text_tag" or "in_text" - local name = propname - local namespace : string - local prefix : string - local single_attribute : string - local enums : { any } - - if propschema is json_schema_object then - 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 - value_where = "in_children" - end - - if propschema is json_schema_object then - local xml = propschema.xml - if xml then - if xml.name then - name = xml.name - end - if xml.namespace and xml.namespace ~= current_ns then - namespace = xml.namespace - end - if xml.prefix then - prefix = xml.prefix - end - if proptype == "array" and xml.wrapped then - value_where = "in_wrapper" - elseif xml.attribute then - value_where = "in_attribute" - elseif xml.text then - value_where = "in_text" - elseif xml.x_name_is_value then - value_where = "in_tag_name" - elseif xml.x_single_attribute then - single_attribute = xml.x_single_attribute - value_where = "in_single_attribute" - end - end - if propschema["const"] then - enums = { propschema["const"] } - elseif propschema["enum"] then - enums = propschema["enum"] - 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 - -local parse_object : function (schema : schema_t, s : st.stanza_t, root : json_schema_object) : { string : any } -local parse_array : function (schema : schema_t, s : st.stanza_t, root : json_schema_object) : { any } - -local function extract_value (s : st.stanza_t, value_where : value_goes, proptype : json.json_type_name, name : string, namespace : string, prefix : string, single_attribute : string, enums : { any }) : string - if value_where == "in_tag_name" then - local c : st.stanza_t - if proptype == "boolean" then - c = s:get_child(name, namespace); - elseif enums and proptype == "string" then - -- XXX O(n²) ? - -- Probably better to flip the table and loop over :childtags(nil, ns), should be 2xO(n) - -- BUT works first, optimize later - for i = 1, #enums do - c = s:get_child(enums[i] as string, namespace); - if c then break end - end - else - c = s:get_child(nil, namespace); - end - if c then - return c.name; - end - elseif value_where == "in_attribute" then - local attr = name - if prefix then - attr = prefix .. ':' .. name - elseif namespace and namespace ~= s.attr.xmlns then - attr = namespace .. "\1" .. name - end - return s.attr[attr] - - elseif value_where == "in_text" then - return s:get_text() - - elseif value_where == "in_single_attribute" then - local c = s:get_child(name, namespace) - return c and c.attr[single_attribute] - elseif value_where == "in_text_tag" then - return s:get_child_text(name, namespace) - end -end - -function parse_object (schema : schema_t, s : st.stanza_t, root : json_schema_object) : { string : any } - local out : { string : any } = {} - schema = resolve_schema(schema, root) - if schema is json_schema_object and schema.properties then - for prop, propschema in pairs(schema.properties) do - propschema = resolve_schema(propschema, root) - - local proptype, value_where, name, namespace, prefix, single_attribute, enums = unpack_propschema(propschema, prop, s.attr.xmlns) - - if value_where == "in_children" and propschema is json_schema_object then - if proptype == "object" then - local c = s:get_child(name, namespace) - if c then - out[prop] = parse_object(propschema, c, root); - end - elseif proptype == "array" then - local a = parse_array(propschema, s, root); - if a and a[1] ~= nil then - out[prop] = a; - end - else - error "unreachable" - end - elseif value_where == "in_wrapper" and propschema is json_schema_object and proptype == "array" then - local wrapper = s:get_child(name, namespace); - if wrapper then - out[prop] = parse_array(propschema, wrapper, root); - end - else - local value : string = extract_value (s, value_where, proptype, name, namespace, prefix, single_attribute, enums) - - out[prop] = totype(proptype, value) - end - end - end - - return out -end - -function parse_array (schema : json_schema_object, s : st.stanza_t, root : json_schema_object) : { any } - local itemschema : schema_t = resolve_schema(schema.items, root); - local proptype, value_where, child_name, namespace, prefix, single_attribute, enums = unpack_propschema(itemschema, nil, s.attr.xmlns) - local attr_name : string - if value_where == "in_single_attribute" then -- FIXME this shouldn't be needed - value_where = "in_attribute"; - attr_name = single_attribute; - end - local out : { any } = {} - - if proptype == "object" then - if itemschema is json_schema_object then - for c in s:childtags(child_name, namespace) do - table.insert(out, parse_object(itemschema, c, root)); - end - else - error "array items must be schema object" - end - elseif proptype == "array" then - if itemschema is json_schema_object then - for c in s:childtags(child_name, namespace) do - table.insert(out, parse_array(itemschema, c, root)); - end - end - else - for c in s:childtags(child_name, namespace) do - local value : string = extract_value (c, value_where, proptype, attr_name or child_name, namespace, prefix, single_attribute, enums) - - table.insert(out, totype(proptype, value)); - end - end - return out; -end - -local function parse (schema : json_schema_object, s : st.stanza_t) : table - local s_type = guess_schema_type(schema) - if s_type == "object" then - return parse_object(schema, s, schema) - elseif s_type == "array" then - return parse_array(schema, s, schema) - else - error "top-level scalars unsupported" - end -end - -local function toxmlstring(proptype : json_type_name, v : any) : string - if proptype == "string" and v is string then - return v - elseif proptype == "number" and v is number then - return string.format("%g", v) - elseif proptype == "integer" and v is number then -- TODO is integer - return string.format("%d", v) - elseif proptype == "boolean" then - return v and "1" or "0" - end -end - -local unparse : function (json_schema_object, table, string, string, st.stanza_t, json_schema_object) : st.stanza_t - -local function unparse_property(out : st.stanza_t, v : any, proptype : json_type_name, propschema : schema_t, value_where : value_goes, name : string, namespace : string, current_ns : string, prefix : string, single_attribute : string, root : json_schema_object) - - if value_where == "in_attribute" then - local attr = name - if prefix then - attr = prefix .. ':' .. name - elseif namespace and namespace ~= current_ns then - attr = namespace .. "\1" .. name - end - - out.attr[attr] = toxmlstring(proptype, v) - elseif value_where == "in_text" then - out:text(toxmlstring(proptype, v)) - elseif value_where == "in_single_attribute" then - assert(single_attribute) - local propattr : { string : string } = {} - - if namespace and namespace ~= current_ns then - propattr.xmlns = namespace - end - - propattr[single_attribute] = toxmlstring(proptype, v) - out:tag(name, propattr):up(); - - else - local propattr : { string : string } - if namespace ~= current_ns then - propattr = { xmlns = namespace } - end - if value_where == "in_tag_name" then - if proptype == "string" and v is string then - out:tag(v, propattr):up(); - elseif proptype == "boolean" and v == true then - out:tag(name, propattr):up(); - end - elseif proptype == "object" and propschema is json_schema_object and v is table then - local c = unparse(propschema, v, name, namespace, nil, root); - if c then - out:add_direct_child(c); - end - elseif proptype == "array" and propschema is json_schema_object and v is table then - if value_where == "in_wrapper" then - local c = unparse(propschema, v, name, namespace, nil, root); - if c then - out:add_direct_child(c); - end - else - unparse(propschema, v, name, namespace, out, root); - end - else - out:text_tag(name, toxmlstring(proptype, v), propattr) - end - end -end - -function unparse ( schema : json_schema_object, t : table, current_name : string, current_ns : string, ctx : st.stanza_t, root : json_schema_object ) : st.stanza_t - - if root == nil then root = schema end - - if schema.xml then - if schema.xml.name then - current_name = schema.xml.name - end - if schema.xml.namespace then - current_ns = schema.xml.namespace - end - -- TODO prefix? - end - - local out = ctx or st.stanza(current_name, { xmlns = current_ns }) - - 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) - local v = t[prop] - - if v ~= nil then - local proptype, value_where, name, namespace, prefix, single_attribute = unpack_propschema(propschema, prop, current_ns) - unparse_property(out, v, proptype, propschema, value_where, name, namespace, current_ns, prefix, single_attribute, root) - end - end - return out; - - 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 - unparse_property(out, item, proptype, itemschema, value_where, name, namespace, current_ns, prefix, single_attribute, root) - end - return out; - end -end - -return { - parse = parse, - unparse = unparse, -} diff --git a/teal-src/util/datetime.d.tl b/teal-src/util/datetime.d.tl deleted file mode 100644 index 971e8f9c..00000000 --- a/teal-src/util/datetime.d.tl +++ /dev/null @@ -1,11 +0,0 @@ --- TODO s/number/integer/ once Teal gets support for that - -local record lib - date : function (t : integer) : string - datetime : function (t : integer) : string - time : function (t : integer) : string - legacy : function (t : integer) : string - parse : function (t : string) : integer -end - -return lib diff --git a/teal-src/util/encodings.d.tl b/teal-src/util/encodings.d.tl deleted file mode 100644 index 58aefa5e..00000000 --- a/teal-src/util/encodings.d.tl +++ /dev/null @@ -1,27 +0,0 @@ --- TODO many actually return Maybe(String) -local record lib - record base64 - encode : function (s : string) : string - decode : function (s : string) : string - end - record stringprep - nameprep : function (s : string, strict : boolean) : string - nodeprep : function (s : string, strict : boolean) : string - resourceprep : function (s : string, strict : boolean) : string - saslprep : function (s : string, strict : boolean) : string - end - record idna - to_ascii : function (s : string) : string - to_unicode : function (s : string) : string - end - record utf8 - valid : function (s : string) : boolean - length : function (s : string) : integer - end - record confusable - skeleton : function (s : string) : string - end - version : string -end -return lib - diff --git a/teal-src/util/error.d.tl b/teal-src/util/error.d.tl deleted file mode 100644 index 05f52405..00000000 --- a/teal-src/util/error.d.tl +++ /dev/null @@ -1,78 +0,0 @@ -local enum error_type - "auth" - "cancel" - "continue" - "modify" - "wait" -end - -local enum error_condition - "bad-request" - "conflict" - "feature-not-implemented" - "forbidden" - "gone" - "internal-server-error" - "item-not-found" - "jid-malformed" - "not-acceptable" - "not-allowed" - "not-authorized" - "policy-violation" - "recipient-unavailable" - "redirect" - "registration-required" - "remote-server-not-found" - "remote-server-timeout" - "resource-constraint" - "service-unavailable" - "subscription-required" - "undefined-condition" - "unexpected-request" -end - -local record protoerror - type : error_type - condition : error_condition - text : string - code : integer -end - -local record error - type : error_type - condition : error_condition - text : string - code : integer - context : { any : any } - source : string -end - -local type compact_registry_item = { string, string, string, string } -local type compact_registry = { compact_registry_item } -local type registry = { string : protoerror } -local type context = { string : any } - -local record error_registry_wrapper - source : string - registry : registry - new : function (string, context) : error - coerce : function (any, string) : any, error - wrap : function (error) : error - wrap : function (string, context) : error - is_error : function (any) : boolean -end - -local record lib - record configure_opt - auto_inject_traceback : boolean - end - new : function (protoerror, context, { string : protoerror }, string) : error - init : function (string, string, registry | compact_registry) : error_registry_wrapper - init : function (string, registry | compact_registry) : error_registry_wrapper - is_error : function (any) : boolean - coerce : function (any, string) : any, error - from_stanza : function (table, context, string) : error - configure : function -end - -return lib diff --git a/teal-src/util/format.d.tl b/teal-src/util/format.d.tl deleted file mode 100644 index 1ff77c97..00000000 --- a/teal-src/util/format.d.tl +++ /dev/null @@ -1,4 +0,0 @@ -local record lib - format : function (string, ... : any) : string -end -return lib diff --git a/teal-src/util/hashes.d.tl b/teal-src/util/hashes.d.tl deleted file mode 100644 index cbb06f8e..00000000 --- a/teal-src/util/hashes.d.tl +++ /dev/null @@ -1,23 +0,0 @@ -local type hash = function (msg : string, hex : boolean) : string -local type hmac = function (key : string, msg : string, hex : boolean) : string -local type kdf = function (pass : string, salt : string, i : integer) : string - -local record lib - sha1 : hash - sha256 : hash - sha224 : hash - sha384 : hash - sha512 : hash - md5 : hash - hmac_sha1 : hmac - hmac_sha256 : hmac - hmac_sha512 : hmac - hmac_md5 : hmac - scram_Hi_sha1 : kdf - pbkdf2_hmac_sha1 : kdf - pbkdf2_hmac_sha256 : kdf - equals : function (string, string) : boolean - version : string - _LIBCRYPTO_VERSION : string -end -return lib diff --git a/teal-src/util/hex.d.tl b/teal-src/util/hex.d.tl deleted file mode 100644 index 3b216a88..00000000 --- a/teal-src/util/hex.d.tl +++ /dev/null @@ -1,6 +0,0 @@ -local type s2s = function (s : string) : string -local record lib - to : s2s - from : s2s -end -return lib diff --git a/teal-src/util/http.d.tl b/teal-src/util/http.d.tl deleted file mode 100644 index ecbe35c3..00000000 --- a/teal-src/util/http.d.tl +++ /dev/null @@ -1,9 +0,0 @@ -local record lib - urlencode : function (s : string) : string - urldecode : function (s : string) : string - formencode : function (f : { string : string }) : string - formdecode : function (s : string) : { string : string } - contains_token : function (field : string, token : string) : boolean - normalize_path : function (path : string) : string -end -return lib diff --git a/teal-src/util/human/units.d.tl b/teal-src/util/human/units.d.tl deleted file mode 100644 index f6568d90..00000000 --- a/teal-src/util/human/units.d.tl +++ /dev/null @@ -1,5 +0,0 @@ -local lib = record - adjust : function (number, string) : number, string - format : function (number, string, string) : string -end -return lib diff --git a/teal-src/util/id.d.tl b/teal-src/util/id.d.tl deleted file mode 100644 index 4b6c93b7..00000000 --- a/teal-src/util/id.d.tl +++ /dev/null @@ -1,9 +0,0 @@ -local record lib - short : function () : string - medium : function () : string - long : function () : string - custom : function (integer) : function () : string - -end -return lib - diff --git a/teal-src/util/interpolation.d.tl b/teal-src/util/interpolation.d.tl deleted file mode 100644 index fb653edf..00000000 --- a/teal-src/util/interpolation.d.tl +++ /dev/null @@ -1,6 +0,0 @@ -local type renderer = function (string, { string : any }) : string -local type filter = function (string, any) : string -local record lib - new : function (string, string, funcs : { string : filter }) : renderer -end -return lib diff --git a/teal-src/util/jid.d.tl b/teal-src/util/jid.d.tl deleted file mode 100644 index 897318d9..00000000 --- a/teal-src/util/jid.d.tl +++ /dev/null @@ -1,15 +0,0 @@ -local record lib - split : function (string) : string, string, string - bare : function (string) : string - prepped_split : function (string, boolean) : string, string, string - join : function (string, string, string) : string - prep : function (string, boolean) : string - compare : function (string, string) : boolean - node : function (string) : string - host : function (string) : string - resource : function (string) : string - escape : function (string) : string - unescape : function (string) : string -end - -return lib diff --git a/teal-src/util/json.d.tl b/teal-src/util/json.d.tl deleted file mode 100644 index a1c25004..00000000 --- a/teal-src/util/json.d.tl +++ /dev/null @@ -1,18 +0,0 @@ -local record lib - encode : function (any) : string - decode : function (string) : any, string - - enum json_type_name - "null" - "boolean" - "object" - "array" - "number" - "string" - "integer" - end - - type null_type = (nil) - null : null_type -end -return lib diff --git a/teal-src/util/jsonpointer.tl b/teal-src/util/jsonpointer.tl deleted file mode 100644 index c21e1fbf..00000000 --- a/teal-src/util/jsonpointer.tl +++ /dev/null @@ -1,46 +0,0 @@ - -local enum ptr_error - "invalid-table" - "invalid-path" -end - -local function unescape_token(escaped_token : string) : string - local unescaped = escaped_token:gsub("~1", "/"):gsub("~0", "~") - return unescaped -end - -local function resolve_json_pointer(ref : table, path : string) : any, ptr_error - local ptr_len = #path+1 - for part, pos in path:gmatch("/([^/]*)()") do - local token = unescape_token(part) - if not ref is table then - return nil - end - local idx = next(ref) - local new_ref : any - - if idx is string then - new_ref = ref[token] - elseif idx is integer then - local i = tonumber(token) - if token == "-" then i = #ref + 1 end - new_ref = ref[i+1] - else - return nil, "invalid-table" - end - - if pos as integer == ptr_len then - return new_ref - elseif new_ref is table then - ref = new_ref - elseif not ref is table then - return nil, "invalid-path" - end - - end - return ref -end - -return { - resolve = resolve_json_pointer, -} diff --git a/teal-src/util/jsonschema.tl b/teal-src/util/jsonschema.tl deleted file mode 100644 index 160c164c..00000000 --- a/teal-src/util/jsonschema.tl +++ /dev/null @@ -1,374 +0,0 @@ --- Copyright (C) 2021 Kim Alvefur --- --- This project is MIT/X11 licensed. Please see the --- COPYING file in the source package for more information. --- --- Based on --- https://json-schema.org/draft/2020-12/json-schema-core.html --- https://json-schema.org/draft/2020-12/json-schema-validation.html --- - -local json = require"util.json" -local null = json.null; - -local pointer = require "util.jsonpointer" - -local type json_type_name = json.json_type_name - --- json_type_name here is non-standard -local type schema_t = boolean | json_schema_object - -local record json_schema_object - type json_type_name = json.json_type_name - type schema_object = json_schema_object - - type : json_type_name | { json_type_name } - enum : { any } - const : any - - allOf : { schema_t } - anyOf : { schema_t } - oneOf : { schema_t } - - ["not"] : schema_t - ["if"] : schema_t - ["then"] : schema_t - ["else"] : schema_t - - ["$ref"] : string - - -- numbers - multipleOf : number - maximum : number - exclusiveMaximum : number - minimum : number - exclusiveMinimum : number - - -- strings - maxLength : integer - minLength : integer - pattern : string -- NYI - format : string - - -- arrays - prefixItems : { schema_t } - items : schema_t - contains : schema_t - maxItems : integer - minItems : integer - uniqueItems : boolean - maxContains : integer -- NYI - minContains : integer -- NYI - - -- objects - properties : { string : schema_t } - maxProperties : integer -- NYI - minProperties : integer -- NYI - required : { string } - dependentRequired : { string : { string } } - additionalProperties: schema_t - patternProperties: schema_t -- NYI - propertyNames : schema_t - - -- xml - record xml_t - name : string - namespace : string - prefix : string - attribute : boolean - wrapped : boolean - - -- nonstantard, maybe in the future - text : boolean - x_name_is_value : boolean - x_single_attribute : string - end - - xml : xml_t - - -- descriptive - title : string - description : string - deprecated : boolean - readOnly : boolean - writeOnly : boolean - - -- methods - validate : function ( schema_t, any, json_schema_object ) : boolean -end - --- TODO validator function per schema property - -local function simple_validate(schema : json_type_name | { json_type_name }, data : any) : boolean - if schema == nil then - return true - elseif schema == "object" and data is table then - return type(data) == "table" and (next(data)==nil or type((next(data, nil))) == "string") - elseif schema == "array" and data is table then - return type(data) == "table" and (next(data)==nil or type((next(data, nil))) == "number") - elseif schema == "integer" then - return math.type(data) == schema - elseif schema == "null" then - return data == null - elseif schema is { json_type_name } then - for _, one in ipairs(schema as { json_type_name }) do - if simple_validate(one, data) then - return true - end - end - return false - else - return type(data) == schema - end -end - -local complex_validate : function ( json_schema_object, any, json_schema_object ) : boolean - -local function validate (schema : schema_t, data : any, root : json_schema_object) : boolean - if schema is boolean then - return schema - else - return complex_validate(schema, data, root) - end -end - -function complex_validate (schema : json_schema_object, data : any, root : json_schema_object) : boolean - - if root == nil then - root = schema - end - - if 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 and referenced ~= root and referenced ~= schema then - if not validate(referenced, data, root) then - return false; - end - end - end - - if not simple_validate(schema.type, data) then - return false; - end - - if schema.type == "object" then - if data is table then - -- just check that there the keys are all strings - for k in pairs(data) do - if not k is string then - return false - end - end - end - end - - if schema.type == "array" then - if data is table then - -- just check that there the keys are all numbers - for i in pairs(data) do - if not i is integer then - return false - end - end - end - end - - if schema["enum"] ~= nil then - local match = false - for _, v in ipairs(schema["enum"]) do - if v == data then - -- FIXME supposed to do deep-compare - match = true - break - end - end - if not match then - return false - end - end - - -- XXX this is measured in byte, while JSON measures in ... bork - -- TODO use utf8.len? - if data is string then - if schema.maxLength and #data > schema.maxLength then - return false - end - if schema.minLength and #data < schema.minLength then - return false - end - end - - if data is number then - if schema.multipleOf and (data == 0 or data % schema.multipleOf ~= 0) then - return false - end - - if schema.maximum and not ( data <= schema.maximum ) then - return false - end - - if schema.exclusiveMaximum and not ( data < schema.exclusiveMaximum ) then - return false - end - - if schema.minimum and not ( data >= schema.minimum ) then - return false - end - - if schema.exclusiveMinimum and not ( data > schema.exclusiveMinimum ) then - return false - end - end - - if schema.allOf then - for _, sub in ipairs(schema.allOf) do - if not validate(sub, data, root) then - return false - end - end - end - - if schema.oneOf then - local valid = 0 - for _, sub in ipairs(schema.oneOf) do - if validate(sub, data, root) then - valid = valid + 1 - end - end - if valid ~= 1 then - return false - end - end - - if schema.anyOf then - local match = false - for _, sub in ipairs(schema.anyOf) do - if validate(sub, data, root) then - match = true - break - end - end - if not match then - return false - end - end - - if schema["not"] then - if validate(schema["not"], data, root) then - return false - end - end - - if schema["if"] ~= nil then - if validate(schema["if"], data, root) then - if schema["then"] then - return validate(schema["then"], data, root) - end - else - if schema["else"] then - return validate(schema["else"], data, root) - end - end - end - - if schema.const ~= nil and schema.const ~= data then - return false - end - - if data is table then - - if schema.maxItems and #data > schema.maxItems then - return false - end - - if schema.minItems and #data < schema.minItems then - return false - end - - if schema.required then - for _, k in ipairs(schema.required) do - if data[k] == nil then - return false - end - end - end - - if schema.propertyNames ~= nil then - for k in pairs(data) do - if not validate(schema.propertyNames, k, root) then - return false - end - end - end - - if schema.properties then - for k, sub in pairs(schema.properties) do - if data[k] ~= nil and not validate(sub, data[k], root) then - return false - end - end - end - - if schema.additionalProperties ~= nil then - for k, v in pairs(data) do - if schema.properties == nil or schema.properties[k as string] == nil then - if not validate(schema.additionalProperties, v, root) then - return false - end - end - end - end - - if schema.uniqueItems then - -- only works for scalars, would need to deep-compare for objects/arrays/tables - local values : { any : boolean } = {} - for _, v in pairs(data) do - if values[v] then - return false - end - values[v] = true - end - end - - local p = 0 - if schema.prefixItems ~= nil then - for i, s in ipairs(schema.prefixItems) do - if data[i] == nil then - break - elseif validate(s, data[i], root) then - p = i - else - return false - end - end - end - - if schema.items ~= nil then - for i = p+1, #data do - if not validate(schema.items, data[i], root) then - return false - end - end - end - - if schema.contains ~= nil then - local found = false - for i = 1, #data do - if validate(schema.contains, data[i], root) then - found = true - break - end - end - if not found then - return false - end - end - end - - return true; -end - - -json_schema_object.validate = validate; - -return json_schema_object; diff --git a/teal-src/util/net.d.tl b/teal-src/util/net.d.tl deleted file mode 100644 index 1040fcef..00000000 --- a/teal-src/util/net.d.tl +++ /dev/null @@ -1,13 +0,0 @@ - -local enum type_strings - "both" - "ipv4" - "ipv6" -end - -local record lib - local_addresses : function (type_strings, boolean) : { string } - pton : function (string):string - ntop : function (string):string -end -return lib diff --git a/teal-src/util/poll.d.tl b/teal-src/util/poll.d.tl deleted file mode 100644 index 8df56d57..00000000 --- a/teal-src/util/poll.d.tl +++ /dev/null @@ -1,31 +0,0 @@ -local record state - enum waiterr - "timeout" - "signal" - end - add : function (state, integer, boolean, boolean) : boolean - add : function (state, integer, boolean, boolean) : nil, string, integer - set : function (state, integer, boolean, boolean) : boolean - set : function (state, integer, boolean, boolean) : nil, string, integer - del : function (state, integer) : boolean - del : function (state, integer) : nil, string, integer - wait : function (state, integer) : integer, boolean, boolean - wait : function (state, integer) : nil, string, integer - wait : function (state, integer) : nil, waiterr - getfd : function (state) : integer -end - -local record lib - new : function () : state - EEXIST : integer - EMFILE : integer - ENOENT : integer - enum api_backend - "epoll" - "poll" - "select" - end - api : api_backend -end - -return lib diff --git a/teal-src/util/pposix.d.tl b/teal-src/util/pposix.d.tl deleted file mode 100644 index 68f49730..00000000 --- a/teal-src/util/pposix.d.tl +++ /dev/null @@ -1,108 +0,0 @@ -local record pposix - enum syslog_facility - "auth" - "authpriv" - "cron" - "daemon" - "ftp" - "kern" - "local0" - "local1" - "local2" - "local3" - "local4" - "local5" - "local6" - "local7" - "lpr" - "mail" - "syslog" - "user" - "uucp" - end - - enum syslog_level - "debug" - "info" - "notice" - "warn" - "error" - end - - enum ulimit_resource - "CORE" - "CPU" - "DATA" - "FSIZE" - "NOFILE" - "STACK" - "MEMLOCK" - "NPROC" - "RSS" - "NICE" - end - - enum ulimit_unlimited - "unlimited" - end - - type ulimit_limit = integer | ulimit_unlimited - - record utsname - sysname : string - nodename : string - release : string - version : string - machine : string - domainname : string - end - - record memoryinfo - allocated : integer - allocated_mmap : integer - used : integer - unused : integer - returnable : integer - end - - abort : function () - - daemonize : function () : boolean, string - - syslog_open : function (ident : string, facility : syslog_facility) - syslog_close : function () - syslog_log : function (level : syslog_level, src : string, msg : string) - syslog_setminlevel : function (level : syslog_level) - - getpid : function () : integer - getuid : function () : integer - getgid : function () : integer - - setuid : function (uid : integer | string) : boolean, string -- string|integer - setgid : function (uid : integer | string) : boolean, string - initgroups : function (user : string, gid : integer) : boolean, string - - umask : function (umask : string) : string - - mkdir : function (dir : string) : boolean, string - - setrlimit : function (resource : ulimit_resource, soft : ulimit_limit, hard : ulimit_limit) : boolean, string - getrlimit : function (resource : ulimit_resource) : boolean, ulimit_limit, ulimit_limit - getrlimit : function (resource : ulimit_resource) : boolean, string - - uname : function () : utsname - - setenv : function (key : string, value : string) : boolean - - meminfo : function () : memoryinfo - - atomic_append : function (f : FILE, s : string) : boolean, string, integer - - isatty : function(FILE) : boolean - - ENOENT : integer - _NAME : string - _VESRION : string -end - -return pposix diff --git a/teal-src/util/random.d.tl b/teal-src/util/random.d.tl deleted file mode 100644 index 83ff2fcc..00000000 --- a/teal-src/util/random.d.tl +++ /dev/null @@ -1,4 +0,0 @@ -local record lib - bytes : function (n:integer):string -end -return lib diff --git a/teal-src/util/ringbuffer.d.tl b/teal-src/util/ringbuffer.d.tl deleted file mode 100644 index e4726d68..00000000 --- a/teal-src/util/ringbuffer.d.tl +++ /dev/null @@ -1,20 +0,0 @@ -local record lib - record ringbuffer - find : function (ringbuffer, string) : integer - discard : function (ringbuffer, integer) : boolean - read : function (ringbuffer, integer, boolean) : string - readuntil : function (ringbuffer, string) : string - write : function (ringbuffer, string) : integer - size : function (ringbuffer) : integer - length : function (ringbuffer) : integer - sub : function (ringbuffer, integer, integer) : string - byte : function (ringbuffer, integer, integer) : integer... - free : function (ringbuffer) : integer - end - - new : function (integer) : ringbuffer -end - -return lib - - diff --git a/teal-src/util/signal.d.tl b/teal-src/util/signal.d.tl deleted file mode 100644 index 8610aa7f..00000000 --- a/teal-src/util/signal.d.tl +++ /dev/null @@ -1,41 +0,0 @@ -local record lib - enum signal - "SIGABRT" - "SIGALRM" - "SIGBUS" - "SIGCHLD" - "SIGCLD" - "SIGCONT" - "SIGFPE" - "SIGHUP" - "SIGILL" - "SIGINT" - "SIGIO" - "SIGIOT" - "SIGKILL" - "SIGPIPE" - "SIGPOLL" - "SIGPROF" - "SIGQUIT" - "SIGSEGV" - "SIGSTKFLT" - "SIGSTOP" - "SIGSYS" - "SIGTERM" - "SIGTRAP" - "SIGTTIN" - "SIGTTOU" - "SIGURG" - "SIGUSR1" - "SIGUSR2" - "SIGVTALRM" - "SIGWINCH" - "SIGXCPU" - "SIGXFSZ" - end - signal : function (integer | signal, function, boolean) : boolean - raise : function (integer | signal) - kill : function (integer, integer | signal) - -- enum : integer -end -return lib diff --git a/teal-src/util/smqueue.tl b/teal-src/util/smqueue.tl deleted file mode 100644 index e149dde7..00000000 --- a/teal-src/util/smqueue.tl +++ /dev/null @@ -1,99 +0,0 @@ -local queue = require "util.queue"; - -local record lib - -- T would typically be util.stanza - record smqueue<T> - _queue : queue.queue<T> - _head : integer - _tail : integer - - enum ack_errors - "tail" - "head" - "pop" - end - push : function (smqueue, T) - ack : function (smqueue, integer) : { T }, ack_errors - resumable : function (smqueue<T>) : boolean - resume : function (smqueue<T>) : queue.queue.iterator, any, integer - type consume_iter = function (smqueue<T>) : T - consume : function (smqueue<T>) : consume_iter - - table : function (smqueue<T>) : { T } - end - new : function <T>(integer) : smqueue<T> -end - -local type smqueue = lib.smqueue; - -function smqueue:push(v) - self._head = self._head + 1; - -- Wraps instead of errors - assert(self._queue:push(v)); -end - -function smqueue:ack(h : integer) : { any }, smqueue.ack_errors - if h < self._tail then - return nil, "tail"; - elseif h > self._head then - return nil, "head"; - end - -- TODO optimize? cache table fields - local acked = {}; - self._tail = h; - local expect = self._head - self._tail; - while expect < self._queue:count() do - local v = self._queue:pop(); - if not v then return nil, "pop"; end - table.insert(acked, v); - end - return acked; -end - -function smqueue:count_unacked() : integer - return self._head - self._tail; -end - -function smqueue:count_acked() : integer - return self._tail; -end - -function smqueue:resumable() : boolean - return self._queue:count() >= (self._head - self._tail); -end - -function smqueue:resume() : queue.queue.iterator, any, integer - return self._queue:items(); -end - -function smqueue:consume() : queue.queue.consume_iter - return self._queue:consume() -end - --- Compatibility layer, plain ol' table -function smqueue:table() : { any } - local t : { any } = {}; - for i, v in self:resume() do - t[i] = v; - end - return t; -end - -local function freeze(q : smqueue<any>) : { string:integer } - return { head = q._head, tail = q._tail } -end - -local queue_mt = { - -- - __name = "smqueue"; - __index = smqueue; - __len = smqueue.count_unacked; - __freeze = freeze; -} - -function lib.new<T>(size : integer) : queue.queue<T> - assert(size>0); - return setmetatable({ _head = 0; _tail = 0; _queue = queue.new(size, true) }, queue_mt); -end - -return lib; diff --git a/teal-src/util/stanza.d.tl b/teal-src/util/stanza.d.tl deleted file mode 100644 index a358248a..00000000 --- a/teal-src/util/stanza.d.tl +++ /dev/null @@ -1,62 +0,0 @@ -local record lib - - type children_iter = function ( stanza_t ) : stanza_t - type childtags_iter = function () : stanza_t - type maptags_cb = function ( stanza_t ) : stanza_t - - record stanza_t - name : string - attr : { string : string } - { stanza_t | string } - tags : { stanza_t } - - query : function ( stanza_t, string ) : stanza_t - body : function ( stanza_t, string, { string : string } ) : stanza_t - text_tag : function ( stanza_t, string, string, { string : string } ) : stanza_t - tag : function ( stanza_t, string, { string : string } ) : stanza_t - text : function ( stanza_t, string ) : stanza_t - up : function ( stanza_t ) : stanza_t - reset : function ( stanza_t ) : stanza_t - add_direct_child : function ( stanza_t, stanza_t ) - add_child : function ( stanza_t, stanza_t ) - remove_children : function ( stanza_t, string, string ) : stanza_t - - get_child : function ( stanza_t, string, string ) : stanza_t - get_text : function ( stanza_t ) : string - get_child_text : function ( stanza_t, string, string ) : string - child_with_name : function ( stanza_t, string, string ) : stanza_t - child_with_ns : function ( stanza_t, string, string ) : stanza_t - children : function ( stanza_t ) : children_iter, stanza_t, integer - childtags : function ( stanza_t, string, string ) : childtags_iter - maptags : function ( stanza_t, maptags_cb ) : stanza_t - find : function ( stanza_t, string ) : stanza_t | string - - top_tag : function ( stanza_t ) : string - pretty_print : function ( stanza_t ) : string - pretty_top_tag : function ( stanza_t ) : string - - get_error : function ( stanza_t ) : string, string, string, stanza_t - indent : function ( stanza_t, integer, string ) : stanza_t - end - - record serialized_stanza_t - name : string - attr : { string : string } - { serialized_stanza_t | string } - end - - stanza : function ( string, { string : string } ) : stanza_t - is_stanza : function ( any ) : boolean - preserialize : function ( stanza_t ) : serialized_stanza_t - deserialize : function ( serialized_stanza_t ) : stanza_t - clone : function ( stanza_t, boolean ) : stanza_t - message : function ( { string : string }, string ) : stanza_t - iq : function ( { string : string } ) : stanza_t - reply : function ( stanza_t ) : stanza_t - error_reply : function ( stanza_t, string, string, string, string ) - presence : function ( { string : string } ) : stanza_t - xml_escape : function ( string ) : string - pretty_print : function ( string ) : string -end - -return lib diff --git a/teal-src/util/strbitop.d.tl b/teal-src/util/strbitop.d.tl deleted file mode 100644 index 010efdb8..00000000 --- a/teal-src/util/strbitop.d.tl +++ /dev/null @@ -1,6 +0,0 @@ -local record mod - sand : function (string, string) : string - sor : function (string, string) : string - sxor : function (string, string) : string -end -return mod diff --git a/teal-src/util/table.d.tl b/teal-src/util/table.d.tl deleted file mode 100644 index 0ff5ed95..00000000 --- a/teal-src/util/table.d.tl +++ /dev/null @@ -1,6 +0,0 @@ -local record lib - create : function (narr:integer, nrec:integer):table - pack : function (...:any):{any} -end -return lib - diff --git a/teal-src/util/time.d.tl b/teal-src/util/time.d.tl deleted file mode 100644 index e159706b..00000000 --- a/teal-src/util/time.d.tl +++ /dev/null @@ -1,6 +0,0 @@ - -local record lib - now : function () : number - monotonic : function () : number -end -return lib diff --git a/teal-src/util/uuid.d.tl b/teal-src/util/uuid.d.tl deleted file mode 100644 index 45fd4312..00000000 --- a/teal-src/util/uuid.d.tl +++ /dev/null @@ -1,8 +0,0 @@ -local record lib - get_nibbles : (number) : string - generate : function () : string - - seed : function (string) -end -return lib - diff --git a/teal-src/util/xtemplate.tl b/teal-src/util/xtemplate.tl deleted file mode 100644 index b3bdc400..00000000 --- a/teal-src/util/xtemplate.tl +++ /dev/null @@ -1,101 +0,0 @@ --- render(template, stanza) --> string --- {path} --> stanza:find(path) --- {{ns}name/child|each({ns}name){sub-template}} - ---[[ -template ::= "{" path ("|" name ("(" args ")")? (template)? )* "}" -path ::= defined by util.stanza -name ::= %w+ -args ::= anything with balanced ( ) pairs -]] - -local s_gsub = string.gsub; -local s_match = string.match; -local s_sub = string.sub; -local t_concat = table.concat; - -local st = require "util.stanza"; - -local type escape_t = function (string) : string -local type filter_t = function (string, string | st.stanza_t, string) : string | st.stanza_t, boolean -local type filter_coll = { string : filter_t } - -local function render(template : string, root : st.stanza_t, escape : escape_t, filters : filter_coll) : string - escape = escape or st.xml_escape; - - return (s_gsub(template, "%b{}", function(block : string) : string - local inner = s_sub(block, 2, -2); - local path, pipe, pos = s_match(inner, "^([^|]+)(|?)()"); - if not path is string then return end - local value : string | st.stanza_t - if path == "." then - value = root; - elseif path == "#" then - value = root:get_text(); - else - value = root:find(path); - end - local is_escaped = false; - - while pipe == "|" do - local func, args, tmpl, p = s_match(inner, "^(%w+)(%b())(%b{})()", pos as integer); - if not func then func, args, p = s_match(inner, "^(%w+)(%b())()", pos as integer); end - if not func then func, tmpl, p = s_match(inner, "^(%w+)(%b{})()", pos as integer); end - if not func then func, p = s_match(inner, "^(%w+)()", pos as integer); end - if not func then break end - if tmpl then tmpl = s_sub(tmpl, 2, -2); end - if args then args = s_sub(args, 2, -2); end - - if func == "each" and tmpl and st.is_stanza(value) then - if not args then value, args = root, path; end - local ns, name = s_match(args, "^(%b{})(.*)$"); - if ns then ns = s_sub(ns, 2, -2); else name, ns = args, nil; end - if ns == "" then ns = nil; end - if name == "" then name = nil; end - local out, i = {}, 1; - for c in (value as st.stanza_t):childtags(name, ns) do - out[i], i = render(tmpl, c, escape, filters), i + 1; - end - value = t_concat(out); - is_escaped = true; - elseif func == "and" and tmpl then - local condition = value; - if args then condition = root:find(args); end - if condition then - value = render(tmpl, root, escape, filters); - is_escaped = true; - end - elseif func == "or" and tmpl then - local condition = value; - if args then condition = root:find(args); end - if not condition then - value = render(tmpl, root, escape, filters); - is_escaped = true; - end - elseif filters and filters[func] then - local f = filters[func]; - if args == nil then - value, is_escaped = f(value, tmpl); - else - value, is_escaped = f(args, value, tmpl); - end - else - error("No such filter function: " .. func); - end - pipe, pos = s_match(inner, "^(|?)()", p as integer); - end - - if value is string then - if not is_escaped then value = escape(value); end - return value; - elseif st.is_stanza(value) then - value = value:get_text(); - if value then - return escape(value); - end - end - return ""; - end)); -end - -return { render = render }; |