@@ -182,6 +182,7 @@ function codectx_mt:_get_loader()
182182end
183183
184184function codectx_mt :as_string ()
185+ self :_get_loader ()
185186 return tab_concat (self ._code_table )
186187end
187188
329330validatorlib .deepeq = deepeq
330331
331332
333+ local function unique_item_in_array (arr )
334+ local existed_items = {}
335+ for i , val in ipairs (arr ) do
336+ if existed_items [val ] then
337+ return false , existed_items [val ], i
338+ end
339+
340+ existed_items [val ] = i
341+ end
342+
343+ return true
344+ end
345+ validatorlib .unique_item_in_array = unique_item_in_array
346+
347+
332348--
333349-- Validation generator
334350--
@@ -746,15 +762,10 @@ generate_validator = function(ctx, schema)
746762 ctx :stmt ( ' end' )
747763 end
748764
749- -- TODO: this is slow as hell, could be optimized by storing value items
750- -- in a spearate set, and calling deepeq only for references.
751765 if schema .uniqueItems then
752- ctx :stmt (sformat (' for i=2, #%s do' , ctx :param (1 )))
753- ctx :stmt ( ' for j=1, i-1 do' )
754- ctx :stmt (sformat (' if %s(%s[i], %s[j]) then' , ctx :libfunc (' lib.deepeq' ), ctx :param (1 ), ctx :param (1 )))
755- ctx :stmt (sformat (' return false, %s("expected unique items but items %%d and %%d are equal", i, j)' , ctx :libfunc (' string.format' )))
756- ctx :stmt ( ' end' )
757- ctx :stmt ( ' end' )
766+ ctx :stmt (sformat (' local ok, item1, item2 = %s(%s)' , ctx :libfunc (' lib.unique_item_in_array' ), ctx :param (1 )))
767+ ctx :stmt (sformat (' if not ok then' , ctx :libfunc (' lib.unique_item_in_array' ), ctx :param (1 )))
768+ ctx :stmt (sformat (' return false, %s("expected unique items but items %%d and %%d are equal", item1, item2)' , ctx :libfunc (' string.format' )))
758769 ctx :stmt ( ' end' )
759770 end
760771 ctx :stmt (' end' ) -- if array
0 commit comments