Skip to content

Commit a64c1f2

Browse files
committed
[schema] use fast path for converting struct schema to map
1 parent b9326e4 commit a64c1f2

File tree

2 files changed

+204
-128
lines changed

2 files changed

+204
-128
lines changed

jdict.m

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,12 +1152,11 @@ function disp(obj)
11521152
return
11531153
end
11541154

1155-
if (isa(schemadata, 'containers.Map'))
1155+
if (isa(schemadata, 'containers.Map') || isa(schemadata, 'dictionary'))
11561156
obj.schema = schemadata;
1157-
elseif (ischar(schemadata) || isa(schemadata, 'string') || isstruct(schemadata))
1158-
if (isstruct(schemadata))
1159-
schemadata = obj.call_('savejson', '', schemadata);
1160-
end
1157+
elseif (isstruct(schemadata))
1158+
obj.schema = struct2map_(schemadata);
1159+
elseif (ischar(schemadata) || isa(schemadata, 'string'))
11611160
% load as containers.Map to preserve special keys like $ref
11621161
obj.schema = obj.call_('loadjson', char(schemadata), 'usemap', 1);
11631162
else
@@ -1325,7 +1324,7 @@ function disp(obj)
13251324
% if subschema found for this path, validate
13261325
if ~isempty(subschema)
13271326
% forcing type when binType is defined
1328-
if isa(subschema, 'containers.Map') && isKey(subschema, 'binType')
1327+
if (isa(subschema, 'containers.Map') || isa(subschema, 'dictionary')) && isKey(subschema, 'binType')
13291328
bintype = subschema('binType');
13301329
if ~isa(value, bintype)
13311330
try
@@ -1610,7 +1609,7 @@ function dispdata_(data, indent, maxdepth, maxlen, hlfun, ulfun)
16101609
fprintf('%s ... (+%d fields)\n', sp, length(fn) - maxlen, hlfun, ulfun);
16111610
end
16121611
end
1613-
elseif isa(data, 'containers.Map')
1612+
elseif isa(data, 'containers.Map') || isa(data, 'dictionary')
16141613
k = keys(data);
16151614
fprintf('Map (%d keys)\n', length(k));
16161615
if maxdepth > 0 && length(k) <= maxlen
@@ -1638,14 +1637,32 @@ function dispdata_(data, indent, maxdepth, maxlen, hlfun, ulfun)
16381637
parts = regexp(datapath, '(?<!\\)\.', 'split');
16391638
for d = 2:length(parts)
16401639
ps = jsonschema(dataschema, [], 'getsubschema', strjoin(parts(1:d), '.'));
1641-
if isempty(ps) && isa(subschema, 'containers.Map') && isKey(subschema, 'additionalProperties') && isequal(subschema('additionalProperties'), false)
1640+
if isempty(ps) && (isa(subschema, 'containers.Map') || isa(subschema, 'dictionary')) && isKey(subschema, 'additionalProperties') && isequal(subschema('additionalProperties'), false)
16421641
errs = {sprintf('"%s" does not allow property "%s"', strjoin(parts(1:d - 1), '.'), parts{d})};
16431642
return
16441643
end
1645-
if d < length(parts) && ~isempty(ps) && isa(ps, 'containers.Map') && isKey(ps, 'type') && ismember(ps('type'), {'integer', 'number', 'string', 'boolean'})
1644+
if d < length(parts) && ~isempty(ps) && (isa(subschema, 'containers.Map') || isa(subschema, 'dictionary')) && isKey(ps, 'type') && ismember(ps('type'), {'integer', 'number', 'string', 'boolean'})
16461645
errs = {sprintf('"%s" expects "%s"', strjoin(parts(1:d), '.'), ps('type'))};
16471646
return
16481647
end
16491648
subschema = ps;
16501649
end
16511650
end
1651+
1652+
function map = struct2map_(s)
1653+
if ~isstruct(s)
1654+
map = s;
1655+
return
1656+
end
1657+
fnames = fieldnames(s);
1658+
vals = cellfun(@(f) convertval_(s.(f)), fnames, 'UniformOutput', false);
1659+
map = containers.Map(fnames, vals, 'UniformValues', false);
1660+
end
1661+
1662+
function v = convertval_(v)
1663+
if isstruct(v)
1664+
v = struct2map_(v);
1665+
elseif iscell(v)
1666+
v = cellfun(@convertval_, v, 'UniformOutput', false);
1667+
end
1668+
end

0 commit comments

Comments
 (0)