1local OptionalType, TaggedType, types 2local FailedTransform = { } 3local unpack = unpack or table.unpack 4local clone_state 5clone_state = function(state_obj) 6 if type(state_obj) ~= "table" then 7 return { } 8 end 9 local out 10 do 11 local _tbl_0 = { } 12 for k, v in pairs(state_obj) do 13 _tbl_0[k] = v 14 end 15 out = _tbl_0 16 end 17 do 18 local mt = getmetatable(state_obj) 19 if mt then 20 setmetatable(out, mt) 21 end 22 end 23 return out 24end 25local BaseType, TransformNode, SequenceNode, FirstOfNode, DescribeNode 26local describe_literal 27describe_literal = function(val) 28 local _exp_0 = type(val) 29 if "string" == _exp_0 then 30 if not val:match('"') then 31 return "\"" .. tostring(val) .. "\"" 32 elseif not val:match("'") then 33 return "'" .. tostring(val) .. "'" 34 else 35 return "`" .. tostring(val) .. "`" 36 end 37 else 38 if BaseType:is_base_type(val) then 39 return val:_describe() 40 else 41 return tostring(val) 42 end 43 end 44end 45local join_names 46join_names = function(items, sep, last_sep) 47 if sep == nil then 48 sep = ", " 49 end 50 local count = #items 51 local chunks = { } 52 for idx, name in ipairs(items) do 53 if idx > 1 then 54 local current_sep 55 if idx == count then 56 current_sep = last_sep or sep 57 else 58 current_sep = sep 59 end 60 table.insert(chunks, current_sep) 61 end 62 table.insert(chunks, name) 63 end 64 return table.concat(chunks) 65end 66do 67 local _class_0 68 local _base_0 = { 69 __eq = function(self, other) 70 if BaseType:is_base_type(other) then 71 return other(self) 72 else 73 return self(other[1]) 74 end 75 end, 76 __div = function(self, fn) 77 return TransformNode(self, fn) 78 end, 79 __mod = function(self, fn) 80 do 81 local _with_0 = TransformNode(self, fn) 82 _with_0.with_state = true 83 return _with_0 84 end 85 end, 86 __mul = function(self, right) 87 return SequenceNode(self, right) 88 end, 89 __add = function(self, right) 90 if self.__class == FirstOfNode then 91 local options = { 92 unpack(self.options) 93 } 94 table.insert(options, right) 95 return FirstOfNode(unpack(options)) 96 else 97 return FirstOfNode(self, right) 98 end 99 end, 100 _describe = function(self) 101 return error("Node missing _describe: " .. tostring(self.__class.__name)) 102 end, 103 check_value = function(self, ...) 104 local value, state_or_err = self:_transform(...) 105 if value == FailedTransform then 106 return nil, state_or_err 107 end 108 if type(state_or_err) == "table" then 109 return state_or_err 110 else 111 return true 112 end 113 end, 114 transform = function(self, ...) 115 local value, state_or_err = self:_transform(...) 116 if value == FailedTransform then 117 return nil, state_or_err 118 end 119 if type(state_or_err) == "table" then 120 return value, state_or_err 121 else 122 return value 123 end 124 end, 125 repair = function(self, ...) 126 return self:transform(...) 127 end, 128 on_repair = function(self, fn) 129 return (self + types.any / fn * self):describe(function() 130 return self:_describe() 131 end) 132 end, 133 is_optional = function(self) 134 return OptionalType(self) 135 end, 136 describe = function(self, ...) 137 return DescribeNode(self, ...) 138 end, 139 tag = function(self, name) 140 return TaggedType(self, { 141 tag = name 142 }) 143 end, 144 clone_opts = function(self, merge) 145 local opts 146 if self.opts then 147 do 148 local _tbl_0 = { } 149 for k, v in pairs(self.opts) do 150 _tbl_0[k] = v 151 end 152 opts = _tbl_0 153 end 154 else 155 opts = { } 156 end 157 if merge then 158 for k, v in pairs(merge) do 159 opts[k] = v 160 end 161 end 162 return opts 163 end, 164 __call = function(self, ...) 165 return self:check_value(...) 166 end 167 } 168 _base_0.__index = _base_0 169 _class_0 = setmetatable({ 170 __init = function(self) 171 if self.opts then 172 self._describe = self.opts.describe 173 end 174 end, 175 __base = _base_0, 176 __name = "BaseType" 177 }, { 178 __index = _base_0, 179 __call = function(cls, ...) 180 local _self_0 = setmetatable({}, _base_0) 181 cls.__init(_self_0, ...) 182 return _self_0 183 end 184 }) 185 _base_0.__class = _class_0 186 local self = _class_0 187 self.is_base_type = function(self, val) 188 if not (type(val) == "table") then 189 return false 190 end 191 local cls = val and val.__class 192 if not (cls) then 193 return false 194 end 195 if BaseType == cls then 196 return true 197 end 198 return self:is_base_type(cls.__parent) 199 end 200 self.__inherited = function(self, cls) 201 cls.__base.__call = cls.__call 202 cls.__base.__eq = self.__eq 203 cls.__base.__div = self.__div 204 cls.__base.__mod = self.__mod 205 cls.__base.__mul = self.__mul 206 cls.__base.__add = self.__add 207 local mt = getmetatable(cls) 208 local create = mt.__call 209 mt.__call = function(cls, ...) 210 local ret = create(cls, ...) 211 if ret.opts and ret.opts.optional then 212 return ret:is_optional() 213 else 214 return ret 215 end 216 end 217 end 218 BaseType = _class_0 219end 220do 221 local _class_0 222 local _parent_0 = BaseType 223 local _base_0 = { 224 _describe = function(self) 225 return self.node:_describe() 226 end, 227 _transform = function(self, value, state) 228 local state_or_err 229 value, state_or_err = self.node:_transform(value, state) 230 if value == FailedTransform then 231 return FailedTransform, state_or_err 232 else 233 local out 234 local _exp_0 = type(self.t_fn) 235 if "function" == _exp_0 then 236 if self.with_state then 237 out = self.t_fn(value, state_or_err) 238 else 239 out = self.t_fn(value) 240 end 241 else 242 out = self.t_fn 243 end 244 return out, state_or_err 245 end 246 end 247 } 248 _base_0.__index = _base_0 249 setmetatable(_base_0, _parent_0.__base) 250 _class_0 = setmetatable({ 251 __init = function(self, node, t_fn) 252 self.node, self.t_fn = node, t_fn 253 return assert(self.node, "missing node for transform") 254 end, 255 __base = _base_0, 256 __name = "TransformNode", 257 __parent = _parent_0 258 }, { 259 __index = function(cls, name) 260 local val = rawget(_base_0, name) 261 if val == nil then 262 local parent = rawget(cls, "__parent") 263 if parent then 264 return parent[name] 265 end 266 else 267 return val 268 end 269 end, 270 __call = function(cls, ...) 271 local _self_0 = setmetatable({}, _base_0) 272 cls.__init(_self_0, ...) 273 return _self_0 274 end 275 }) 276 _base_0.__class = _class_0 277 local self = _class_0 278 self.transformer = true 279 if _parent_0.__inherited then 280 _parent_0.__inherited(_parent_0, _class_0) 281 end 282 TransformNode = _class_0 283end 284do 285 local _class_0 286 local _parent_0 = BaseType 287 local _base_0 = { 288 _describe = function(self) 289 local item_names 290 do 291 local _accum_0 = { } 292 local _len_0 = 1 293 local _list_0 = self.sequence 294 for _index_0 = 1, #_list_0 do 295 local i = _list_0[_index_0] 296 if type(i) == "table" and i._describe then 297 _accum_0[_len_0] = i:_describe() 298 else 299 _accum_0[_len_0] = describe_literal(i) 300 end 301 _len_0 = _len_0 + 1 302 end 303 item_names = _accum_0 304 end 305 return join_names(item_names, " then ") 306 end, 307 _transform = function(self, value, state) 308 local _list_0 = self.sequence 309 for _index_0 = 1, #_list_0 do 310 local node = _list_0[_index_0] 311 value, state = node:_transform(value, state) 312 if value == FailedTransform then 313 break 314 end 315 end 316 return value, state 317 end 318 } 319 _base_0.__index = _base_0 320 setmetatable(_base_0, _parent_0.__base) 321 _class_0 = setmetatable({ 322 __init = function(self, ...) 323 self.sequence = { 324 ... 325 } 326 end, 327 __base = _base_0, 328 __name = "SequenceNode", 329 __parent = _parent_0 330 }, { 331 __index = function(cls, name) 332 local val = rawget(_base_0, name) 333 if val == nil then 334 local parent = rawget(cls, "__parent") 335 if parent then 336 return parent[name] 337 end 338 else 339 return val 340 end 341 end, 342 __call = function(cls, ...) 343 local _self_0 = setmetatable({}, _base_0) 344 cls.__init(_self_0, ...) 345 return _self_0 346 end 347 }) 348 _base_0.__class = _class_0 349 local self = _class_0 350 self.transformer = true 351 if _parent_0.__inherited then 352 _parent_0.__inherited(_parent_0, _class_0) 353 end 354 SequenceNode = _class_0 355end 356do 357 local _class_0 358 local _parent_0 = BaseType 359 local _base_0 = { 360 _describe = function(self) 361 local item_names 362 do 363 local _accum_0 = { } 364 local _len_0 = 1 365 local _list_0 = self.options 366 for _index_0 = 1, #_list_0 do 367 local i = _list_0[_index_0] 368 if type(i) == "table" and i._describe then 369 _accum_0[_len_0] = i:_describe() 370 else 371 _accum_0[_len_0] = describe_literal(i) 372 end 373 _len_0 = _len_0 + 1 374 end 375 item_names = _accum_0 376 end 377 return join_names(item_names, ", ", ", or ") 378 end, 379 _transform = function(self, value, state) 380 if not (self.options[1]) then 381 return FailedTransform, "no options for node" 382 end 383 local _list_0 = self.options 384 for _index_0 = 1, #_list_0 do 385 local node = _list_0[_index_0] 386 local new_val, new_state = node:_transform(value, state) 387 if not (new_val == FailedTransform) then 388 return new_val, new_state 389 end 390 end 391 return FailedTransform, "expected " .. tostring(self:_describe()) 392 end 393 } 394 _base_0.__index = _base_0 395 setmetatable(_base_0, _parent_0.__base) 396 _class_0 = setmetatable({ 397 __init = function(self, ...) 398 self.options = { 399 ... 400 } 401 end, 402 __base = _base_0, 403 __name = "FirstOfNode", 404 __parent = _parent_0 405 }, { 406 __index = function(cls, name) 407 local val = rawget(_base_0, name) 408 if val == nil then 409 local parent = rawget(cls, "__parent") 410 if parent then 411 return parent[name] 412 end 413 else 414 return val 415 end 416 end, 417 __call = function(cls, ...) 418 local _self_0 = setmetatable({}, _base_0) 419 cls.__init(_self_0, ...) 420 return _self_0 421 end 422 }) 423 _base_0.__class = _class_0 424 local self = _class_0 425 self.transformer = true 426 if _parent_0.__inherited then 427 _parent_0.__inherited(_parent_0, _class_0) 428 end 429 FirstOfNode = _class_0 430end 431do 432 local _class_0 433 local _parent_0 = BaseType 434 local _base_0 = { 435 _transform = function(self, input, ...) 436 local value, state = self.node:_transform(input, ...) 437 if value == FailedTransform then 438 local err 439 if self.err_handler then 440 err = self.err_handler(input, state) 441 else 442 err = "expected " .. tostring(self:_describe()) 443 end 444 return FailedTransform, err 445 end 446 return value, state 447 end, 448 describe = function(self, ...) 449 return DescribeNode(self.node, ...) 450 end 451 } 452 _base_0.__index = _base_0 453 setmetatable(_base_0, _parent_0.__base) 454 _class_0 = setmetatable({ 455 __init = function(self, node, describe) 456 self.node = node 457 local err_message 458 if type(describe) == "table" then 459 describe, err_message = describe.type, describe.error 460 end 461 if type(describe) == "string" then 462 self._describe = function() 463 return describe 464 end 465 else 466 self._describe = describe 467 end 468 if err_message then 469 if type(err_message) == "string" then 470 self.err_handler = function() 471 return err_message 472 end 473 else 474 self.err_handler = err_message 475 end 476 end 477 end, 478 __base = _base_0, 479 __name = "DescribeNode", 480 __parent = _parent_0 481 }, { 482 __index = function(cls, name) 483 local val = rawget(_base_0, name) 484 if val == nil then 485 local parent = rawget(cls, "__parent") 486 if parent then 487 return parent[name] 488 end 489 else 490 return val 491 end 492 end, 493 __call = function(cls, ...) 494 local _self_0 = setmetatable({}, _base_0) 495 cls.__init(_self_0, ...) 496 return _self_0 497 end 498 }) 499 _base_0.__class = _class_0 500 if _parent_0.__inherited then 501 _parent_0.__inherited(_parent_0, _class_0) 502 end 503 DescribeNode = _class_0 504end 505do 506 local _class_0 507 local _parent_0 = BaseType 508 local _base_0 = { 509 update_state = function(self, state, value, ...) 510 local out = clone_state(state) 511 if self.tag_type == "function" then 512 if select("#", ...) > 0 then 513 self.tag_name(out, ..., value) 514 else 515 self.tag_name(out, value) 516 end 517 else 518 if self.tag_array then 519 local existing = out[self.tag_name] 520 if type(existing) == "table" then 521 local copy 522 do 523 local _tbl_0 = { } 524 for k, v in pairs(existing) do 525 _tbl_0[k] = v 526 end 527 copy = _tbl_0 528 end 529 table.insert(copy, value) 530 out[self.tag_name] = copy 531 else 532 out[self.tag_name] = { 533 value 534 } 535 end 536 else 537 out[self.tag_name] = value 538 end 539 end 540 return out 541 end, 542 _transform = function(self, value, state) 543 value, state = self.base_type:_transform(value, state) 544 if value == FailedTransform then 545 return FailedTransform, state 546 end 547 state = self:update_state(state, value) 548 return value, state 549 end, 550 _describe = function(self) 551 local base_description = self.base_type:_describe() 552 return tostring(base_description) .. " tagged " .. tostring(describe_literal(self.tag)) 553 end 554 } 555 _base_0.__index = _base_0 556 setmetatable(_base_0, _parent_0.__base) 557 _class_0 = setmetatable({ 558 __init = function(self, base_type, opts) 559 self.base_type = base_type 560 self.tag_name = assert(opts.tag, "tagged type missing tag") 561 self.tag_type = type(self.tag_name) 562 if self.tag_type == "string" then 563 if self.tag_name:match("%[%]$") then 564 self.tag_name = self.tag_name:sub(1, -3) 565 self.tag_array = true 566 end 567 end 568 end, 569 __base = _base_0, 570 __name = "TaggedType", 571 __parent = _parent_0 572 }, { 573 __index = function(cls, name) 574 local val = rawget(_base_0, name) 575 if val == nil then 576 local parent = rawget(cls, "__parent") 577 if parent then 578 return parent[name] 579 end 580 else 581 return val 582 end 583 end, 584 __call = function(cls, ...) 585 local _self_0 = setmetatable({}, _base_0) 586 cls.__init(_self_0, ...) 587 return _self_0 588 end 589 }) 590 _base_0.__class = _class_0 591 if _parent_0.__inherited then 592 _parent_0.__inherited(_parent_0, _class_0) 593 end 594 TaggedType = _class_0 595end 596local TagScopeType 597do 598 local _class_0 599 local _parent_0 = TaggedType 600 local _base_0 = { 601 create_scope_state = function(self, state) 602 return nil 603 end, 604 _transform = function(self, value, state) 605 local scope 606 value, scope = self.base_type:_transform(value, self:create_scope_state(state)) 607 if value == FailedTransform then 608 return FailedTransform, scope 609 end 610 if self.tag_name then 611 state = self:update_state(state, scope, value) 612 end 613 return value, state 614 end 615 } 616 _base_0.__index = _base_0 617 setmetatable(_base_0, _parent_0.__base) 618 _class_0 = setmetatable({ 619 __init = function(self, base_type, opts) 620 if opts then 621 return _class_0.__parent.__init(self, base_type, opts) 622 else 623 self.base_type = base_type 624 end 625 end, 626 __base = _base_0, 627 __name = "TagScopeType", 628 __parent = _parent_0 629 }, { 630 __index = function(cls, name) 631 local val = rawget(_base_0, name) 632 if val == nil then 633 local parent = rawget(cls, "__parent") 634 if parent then 635 return parent[name] 636 end 637 else 638 return val 639 end 640 end, 641 __call = function(cls, ...) 642 local _self_0 = setmetatable({}, _base_0) 643 cls.__init(_self_0, ...) 644 return _self_0 645 end 646 }) 647 _base_0.__class = _class_0 648 if _parent_0.__inherited then 649 _parent_0.__inherited(_parent_0, _class_0) 650 end 651 TagScopeType = _class_0 652end 653do 654 local _class_0 655 local _parent_0 = BaseType 656 local _base_0 = { 657 _transform = function(self, value, state) 658 if value == nil then 659 return value, state 660 end 661 return self.base_type:_transform(value, state) 662 end, 663 is_optional = function(self) 664 return self 665 end, 666 _describe = function(self) 667 if self.base_type._describe then 668 local base_description = self.base_type:_describe() 669 return "optional " .. tostring(base_description) 670 end 671 end 672 } 673 _base_0.__index = _base_0 674 setmetatable(_base_0, _parent_0.__base) 675 _class_0 = setmetatable({ 676 __init = function(self, base_type, opts) 677 self.base_type, self.opts = base_type, opts 678 _class_0.__parent.__init(self) 679 return assert(BaseType:is_base_type(base_type), "expected a type checker") 680 end, 681 __base = _base_0, 682 __name = "OptionalType", 683 __parent = _parent_0 684 }, { 685 __index = function(cls, name) 686 local val = rawget(_base_0, name) 687 if val == nil then 688 local parent = rawget(cls, "__parent") 689 if parent then 690 return parent[name] 691 end 692 else 693 return val 694 end 695 end, 696 __call = function(cls, ...) 697 local _self_0 = setmetatable({}, _base_0) 698 cls.__init(_self_0, ...) 699 return _self_0 700 end 701 }) 702 _base_0.__class = _class_0 703 if _parent_0.__inherited then 704 _parent_0.__inherited(_parent_0, _class_0) 705 end 706 OptionalType = _class_0 707end 708local AnyType 709do 710 local _class_0 711 local _parent_0 = BaseType 712 local _base_0 = { 713 _transform = function(self, v, state) 714 return v, state 715 end, 716 _describe = function(self) 717 return "anything" 718 end, 719 is_optional = function(self) 720 return self 721 end 722 } 723 _base_0.__index = _base_0 724 setmetatable(_base_0, _parent_0.__base) 725 _class_0 = setmetatable({ 726 __init = function(self, ...) 727 return _class_0.__parent.__init(self, ...) 728 end, 729 __base = _base_0, 730 __name = "AnyType", 731 __parent = _parent_0 732 }, { 733 __index = function(cls, name) 734 local val = rawget(_base_0, name) 735 if val == nil then 736 local parent = rawget(cls, "__parent") 737 if parent then 738 return parent[name] 739 end 740 else 741 return val 742 end 743 end, 744 __call = function(cls, ...) 745 local _self_0 = setmetatable({}, _base_0) 746 cls.__init(_self_0, ...) 747 return _self_0 748 end 749 }) 750 _base_0.__class = _class_0 751 if _parent_0.__inherited then 752 _parent_0.__inherited(_parent_0, _class_0) 753 end 754 AnyType = _class_0 755end 756local Type 757do 758 local _class_0 759 local _parent_0 = BaseType 760 local _base_0 = { 761 _transform = function(self, value, state) 762 local got = type(value) 763 if self.t ~= got then 764 return FailedTransform, "expected type " .. tostring(describe_literal(self.t)) .. ", got " .. tostring(describe_literal(got)) 765 end 766 if self.length_type then 767 local len = #value 768 local res 769 res, state = self.length_type:_transform(len, state) 770 if res == FailedTransform then 771 return FailedTransform, tostring(self.t) .. " length " .. tostring(state) .. ", got " .. tostring(len) 772 end 773 end 774 return value, state 775 end, 776 length = function(self, left, right) 777 local l 778 if BaseType:is_base_type(left) then 779 l = left 780 else 781 l = types.range(left, right) 782 end 783 return Type(self.t, self:clone_opts({ 784 length = l 785 })) 786 end, 787 _describe = function(self) 788 local t = "type " .. tostring(describe_literal(self.t)) 789 if self.length_type then 790 t = t .. " length_type " .. tostring(self.length_type:_describe()) 791 end 792 return t 793 end 794 } 795 _base_0.__index = _base_0 796 setmetatable(_base_0, _parent_0.__base) 797 _class_0 = setmetatable({ 798 __init = function(self, t, opts) 799 self.t, self.opts = t, opts 800 if self.opts then 801 self.length_type = self.opts.length 802 end 803 return _class_0.__parent.__init(self) 804 end, 805 __base = _base_0, 806 __name = "Type", 807 __parent = _parent_0 808 }, { 809 __index = function(cls, name) 810 local val = rawget(_base_0, name) 811 if val == nil then 812 local parent = rawget(cls, "__parent") 813 if parent then 814 return parent[name] 815 end 816 else 817 return val 818 end 819 end, 820 __call = function(cls, ...) 821 local _self_0 = setmetatable({}, _base_0) 822 cls.__init(_self_0, ...) 823 return _self_0 824 end 825 }) 826 _base_0.__class = _class_0 827 if _parent_0.__inherited then 828 _parent_0.__inherited(_parent_0, _class_0) 829 end 830 Type = _class_0 831end 832local ArrayType 833do 834 local _class_0 835 local _parent_0 = BaseType 836 local _base_0 = { 837 _describe = function(self) 838 return "an array" 839 end, 840 _transform = function(self, value, state) 841 if not (type(value) == "table") then 842 return FailedTransform, "expecting table" 843 end 844 local k = 1 845 for i, v in pairs(value) do 846 if not (type(i) == "number") then 847 return FailedTransform, "non number field: " .. tostring(i) 848 end 849 if not (i == k) then 850 return FailedTransform, "non array index, got " .. tostring(describe_literal(i)) .. " but expected " .. tostring(describe_literal(k)) 851 end 852 k = k + 1 853 end 854 return value, state 855 end 856 } 857 _base_0.__index = _base_0 858 setmetatable(_base_0, _parent_0.__base) 859 _class_0 = setmetatable({ 860 __init = function(self, opts) 861 self.opts = opts 862 return _class_0.__parent.__init(self) 863 end, 864 __base = _base_0, 865 __name = "ArrayType", 866 __parent = _parent_0 867 }, { 868 __index = function(cls, name) 869 local val = rawget(_base_0, name) 870 if val == nil then 871 local parent = rawget(cls, "__parent") 872 if parent then 873 return parent[name] 874 end 875 else 876 return val 877 end 878 end, 879 __call = function(cls, ...) 880 local _self_0 = setmetatable({}, _base_0) 881 cls.__init(_self_0, ...) 882 return _self_0 883 end 884 }) 885 _base_0.__class = _class_0 886 if _parent_0.__inherited then 887 _parent_0.__inherited(_parent_0, _class_0) 888 end 889 ArrayType = _class_0 890end 891local OneOf 892do 893 local _class_0 894 local _parent_0 = BaseType 895 local _base_0 = { 896 _describe = function(self) 897 local item_names 898 do 899 local _accum_0 = { } 900 local _len_0 = 1 901 local _list_0 = self.options 902 for _index_0 = 1, #_list_0 do 903 local i = _list_0[_index_0] 904 if type(i) == "table" and i._describe then 905 _accum_0[_len_0] = i:_describe() 906 else 907 _accum_0[_len_0] = describe_literal(i) 908 end 909 _len_0 = _len_0 + 1 910 end 911 item_names = _accum_0 912 end 913 return tostring(join_names(item_names, ", ", ", or ")) 914 end, 915 _transform = function(self, value, state) 916 if self.options_hash then 917 if self.options_hash[value] then 918 return value, state 919 end 920 else 921 local _list_0 = self.options 922 for _index_0 = 1, #_list_0 do 923 local _continue_0 = false 924 repeat 925 local item = _list_0[_index_0] 926 if item == value then 927 return value, state 928 end 929 if BaseType:is_base_type(item) then 930 local new_value, new_state = item:_transform(value, state) 931 if new_value == FailedTransform then 932 _continue_0 = true 933 break 934 end 935 return new_value, new_state 936 end 937 _continue_0 = true 938 until true 939 if not _continue_0 then 940 break 941 end 942 end 943 end 944 return FailedTransform, "expected " .. tostring(self:_describe()) 945 end 946 } 947 _base_0.__index = _base_0 948 setmetatable(_base_0, _parent_0.__base) 949 _class_0 = setmetatable({ 950 __init = function(self, options, opts) 951 self.options, self.opts = options, opts 952 _class_0.__parent.__init(self) 953 assert(type(self.options) == "table", "expected table for options in one_of") 954 local fast_opts = types.array_of(types.number + types.string) 955 if fast_opts(self.options) then 956 do 957 local _tbl_0 = { } 958 local _list_0 = self.options 959 for _index_0 = 1, #_list_0 do 960 local v = _list_0[_index_0] 961 _tbl_0[v] = true 962 end 963 self.options_hash = _tbl_0 964 end 965 end 966 end, 967 __base = _base_0, 968 __name = "OneOf", 969 __parent = _parent_0 970 }, { 971 __index = function(cls, name) 972 local val = rawget(_base_0, name) 973 if val == nil then 974 local parent = rawget(cls, "__parent") 975 if parent then 976 return parent[name] 977 end 978 else 979 return val 980 end 981 end, 982 __call = function(cls, ...) 983 local _self_0 = setmetatable({}, _base_0) 984 cls.__init(_self_0, ...) 985 return _self_0 986 end 987 }) 988 _base_0.__class = _class_0 989 if _parent_0.__inherited then 990 _parent_0.__inherited(_parent_0, _class_0) 991 end 992 OneOf = _class_0 993end 994local AllOf 995do 996 local _class_0 997 local _parent_0 = BaseType 998 local _base_0 = { 999 _describe = function(self) 1000 local item_names 1001 do 1002 local _accum_0 = { } 1003 local _len_0 = 1 1004 local _list_0 = self.types 1005 for _index_0 = 1, #_list_0 do 1006 local i = _list_0[_index_0] 1007 if type(i) == "table" and i._describe then 1008 _accum_0[_len_0] = i:_describe() 1009 else 1010 _accum_0[_len_0] = describe_literal(i) 1011 end 1012 _len_0 = _len_0 + 1 1013 end 1014 item_names = _accum_0 1015 end 1016 return join_names(item_names, " and ") 1017 end, 1018 _transform = function(self, value, state) 1019 local _list_0 = self.types 1020 for _index_0 = 1, #_list_0 do 1021 local t = _list_0[_index_0] 1022 value, state = t:_transform(value, state) 1023 if value == FailedTransform then 1024 return FailedTransform, state 1025 end 1026 end 1027 return value, state 1028 end 1029 } 1030 _base_0.__index = _base_0 1031 setmetatable(_base_0, _parent_0.__base) 1032 _class_0 = setmetatable({ 1033 __init = function(self, types, opts) 1034 self.types, self.opts = types, opts 1035 _class_0.__parent.__init(self) 1036 assert(type(self.types) == "table", "expected table for first argument") 1037 local _list_0 = self.types 1038 for _index_0 = 1, #_list_0 do 1039 local checker = _list_0[_index_0] 1040 assert(BaseType:is_base_type(checker), "all_of expects all type checkers") 1041 end 1042 end, 1043 __base = _base_0, 1044 __name = "AllOf", 1045 __parent = _parent_0 1046 }, { 1047 __index = function(cls, name) 1048 local val = rawget(_base_0, name) 1049 if val == nil then 1050 local parent = rawget(cls, "__parent") 1051 if parent then 1052 return parent[name] 1053 end 1054 else 1055 return val 1056 end 1057 end, 1058 __call = function(cls, ...) 1059 local _self_0 = setmetatable({}, _base_0) 1060 cls.__init(_self_0, ...) 1061 return _self_0 1062 end 1063 }) 1064 _base_0.__class = _class_0 1065 if _parent_0.__inherited then 1066 _parent_0.__inherited(_parent_0, _class_0) 1067 end 1068 AllOf = _class_0 1069end 1070local ArrayOf 1071do 1072 local _class_0 1073 local _parent_0 = BaseType 1074 local _base_0 = { 1075 _describe = function(self) 1076 return "array of " .. tostring(describe_literal(self.expected)) 1077 end, 1078 _transform = function(self, value, state) 1079 local pass, err = types.table(value) 1080 if not (pass) then 1081 return FailedTransform, err 1082 end 1083 if self.length_type then 1084 local len = #value 1085 local res 1086 res, state = self.length_type:_transform(len, state) 1087 if res == FailedTransform then 1088 return FailedTransform, "array length " .. tostring(state) .. ", got " .. tostring(len) 1089 end 1090 end 1091 local is_literal = not BaseType:is_base_type(self.expected) 1092 local copy, k 1093 for idx, item in ipairs(value) do 1094 local skip_item = false 1095 local transformed_item 1096 if is_literal then 1097 if self.expected ~= item then 1098 return FailedTransform, "array item " .. tostring(idx) .. ": expected " .. tostring(describe_literal(self.expected)) 1099 else 1100 transformed_item = item 1101 end 1102 else 1103 local item_val 1104 item_val, state = self.expected:_transform(item, state) 1105 if item_val == FailedTransform then 1106 return FailedTransform, "array item " .. tostring(idx) .. ": " .. tostring(state) 1107 end 1108 if item_val == nil and not self.keep_nils then 1109 skip_item = true 1110 else 1111 transformed_item = item_val 1112 end 1113 end 1114 if transformed_item ~= item or skip_item then 1115 if not (copy) then 1116 do 1117 local _accum_0 = { } 1118 local _len_0 = 1 1119 local _max_0 = idx - 1 1120 for _index_0 = 1, _max_0 < 0 and #value + _max_0 or _max_0 do 1121 local i = value[_index_0] 1122 _accum_0[_len_0] = i 1123 _len_0 = _len_0 + 1 1124 end 1125 copy = _accum_0 1126 end 1127 k = idx 1128 end 1129 end 1130 if copy and not skip_item then 1131 copy[k] = transformed_item 1132 k = k + 1 1133 end 1134 end 1135 return copy or value, state 1136 end 1137 } 1138 _base_0.__index = _base_0 1139 setmetatable(_base_0, _parent_0.__base) 1140 _class_0 = setmetatable({ 1141 __init = function(self, expected, opts) 1142 self.expected, self.opts = expected, opts 1143 if self.opts then 1144 self.keep_nils = self.opts.keep_nils 1145 self.length_type = self.opts.length 1146 end 1147 return _class_0.__parent.__init(self) 1148 end, 1149 __base = _base_0, 1150 __name = "ArrayOf", 1151 __parent = _parent_0 1152 }, { 1153 __index = function(cls, name) 1154 local val = rawget(_base_0, name) 1155 if val == nil then 1156 local parent = rawget(cls, "__parent") 1157 if parent then 1158 return parent[name] 1159 end 1160 else 1161 return val 1162 end 1163 end, 1164 __call = function(cls, ...) 1165 local _self_0 = setmetatable({}, _base_0) 1166 cls.__init(_self_0, ...) 1167 return _self_0 1168 end 1169 }) 1170 _base_0.__class = _class_0 1171 local self = _class_0 1172 self.type_err_message = "expecting table" 1173 if _parent_0.__inherited then 1174 _parent_0.__inherited(_parent_0, _class_0) 1175 end 1176 ArrayOf = _class_0 1177end 1178local MapOf 1179do 1180 local _class_0 1181 local _parent_0 = BaseType 1182 local _base_0 = { 1183 _transform = function(self, value, state) 1184 local pass, err = types.table(value) 1185 if not (pass) then 1186 return FailedTransform, err 1187 end 1188 local key_literal = not BaseType:is_base_type(self.expected_key) 1189 local value_literal = not BaseType:is_base_type(self.expected_value) 1190 local transformed = false 1191 local out = { } 1192 for k, v in pairs(value) do 1193 local _continue_0 = false 1194 repeat 1195 local new_k = k 1196 local new_v = v 1197 if key_literal then 1198 if k ~= self.expected_key then 1199 return FailedTransform, "map key expected " .. tostring(describe_literal(self.expected_key)) 1200 end 1201 else 1202 new_k, state = self.expected_key:_transform(k, state) 1203 if new_k == FailedTransform then 1204 return FailedTransform, "map key " .. tostring(state) 1205 end 1206 end 1207 if value_literal then 1208 if v ~= self.expected_value then 1209 return FailedTransform, "map value expected " .. tostring(describe_literal(self.expected_value)) 1210 end 1211 else 1212 new_v, state = self.expected_value:_transform(v, state) 1213 if new_v == FailedTransform then 1214 return FailedTransform, "map value " .. tostring(state) 1215 end 1216 end 1217 if new_k ~= k or new_v ~= v then 1218 transformed = true 1219 end 1220 if new_k == nil then 1221 _continue_0 = true 1222 break 1223 end 1224 out[new_k] = new_v 1225 _continue_0 = true 1226 until true 1227 if not _continue_0 then 1228 break 1229 end 1230 end 1231 return transformed and out or value, state 1232 end 1233 } 1234 _base_0.__index = _base_0 1235 setmetatable(_base_0, _parent_0.__base) 1236 _class_0 = setmetatable({ 1237 __init = function(self, expected_key, expected_value, opts) 1238 self.expected_key, self.expected_value, self.opts = expected_key, expected_value, opts 1239 return _class_0.__parent.__init(self) 1240 end, 1241 __base = _base_0, 1242 __name = "MapOf", 1243 __parent = _parent_0 1244 }, { 1245 __index = function(cls, name) 1246 local val = rawget(_base_0, name) 1247 if val == nil then 1248 local parent = rawget(cls, "__parent") 1249 if parent then 1250 return parent[name] 1251 end 1252 else 1253 return val 1254 end 1255 end, 1256 __call = function(cls, ...) 1257 local _self_0 = setmetatable({}, _base_0) 1258 cls.__init(_self_0, ...) 1259 return _self_0 1260 end 1261 }) 1262 _base_0.__class = _class_0 1263 if _parent_0.__inherited then 1264 _parent_0.__inherited(_parent_0, _class_0) 1265 end 1266 MapOf = _class_0 1267end 1268local Shape 1269do 1270 local _class_0 1271 local _parent_0 = BaseType 1272 local _base_0 = { 1273 is_open = function(self) 1274 return Shape(self.shape, self:clone_opts({ 1275 open = true 1276 })) 1277 end, 1278 _describe = function(self) 1279 local parts 1280 do 1281 local _accum_0 = { } 1282 local _len_0 = 1 1283 for k, v in pairs(self.shape) do 1284 _accum_0[_len_0] = tostring(describe_literal(k)) .. " = " .. tostring(describe_literal(v)) 1285 _len_0 = _len_0 + 1 1286 end 1287 parts = _accum_0 1288 end 1289 return "{ " .. tostring(table.concat(parts, ", ")) .. " }" 1290 end, 1291 _transform = function(self, value, state) 1292 local pass, err = types.table(value) 1293 if not (pass) then 1294 return FailedTransform, err 1295 end 1296 local check_all = self.check_all 1297 local remaining_keys 1298 do 1299 local _tbl_0 = { } 1300 for key in pairs(value) do 1301 _tbl_0[key] = true 1302 end 1303 remaining_keys = _tbl_0 1304 end 1305 local errors 1306 local dirty = false 1307 local out = { } 1308 for shape_key, shape_val in pairs(self.shape) do 1309 local item_value = value[shape_key] 1310 if remaining_keys then 1311 remaining_keys[shape_key] = nil 1312 end 1313 local new_val 1314 if BaseType:is_base_type(shape_val) then 1315 new_val, state = shape_val:_transform(item_value, state) 1316 else 1317 if shape_val == item_value then 1318 new_val, state = item_value, state 1319 else 1320 new_val, state = FailedTransform, "expected " .. tostring(describe_literal(shape_val)) 1321 end 1322 end 1323 if new_val == FailedTransform then 1324 err = "field " .. tostring(describe_literal(shape_key)) .. ": " .. tostring(state) 1325 if check_all then 1326 if errors then 1327 table.insert(errors, err) 1328 else 1329 errors = { 1330 err 1331 } 1332 end 1333 else 1334 return FailedTransform, err 1335 end 1336 else 1337 if new_val ~= item_value then 1338 dirty = true 1339 end 1340 out[shape_key] = new_val 1341 end 1342 end 1343 if remaining_keys and next(remaining_keys) then 1344 if self.open then 1345 for k in pairs(remaining_keys) do 1346 out[k] = value[k] 1347 end 1348 elseif self.extra_fields_type then 1349 for k in pairs(remaining_keys) do 1350 local item_value = value[k] 1351 local tuple 1352 tuple, state = self.extra_fields_type:_transform({ 1353 [k] = item_value 1354 }, state) 1355 if tuple == FailedTransform then 1356 err = "field " .. tostring(describe_literal(k)) .. ": " .. tostring(state) 1357 if check_all then 1358 if errors then 1359 table.insert(errors, err) 1360 else 1361 errors = { 1362 err 1363 } 1364 end 1365 else 1366 return FailedTransform, err 1367 end 1368 else 1369 do 1370 local nk = tuple and next(tuple) 1371 if nk then 1372 if nk ~= k then 1373 dirty = true 1374 elseif tuple[nk] ~= item_value then 1375 dirty = true 1376 end 1377 out[nk] = tuple[nk] 1378 else 1379 dirty = true 1380 end 1381 end 1382 end 1383 end 1384 else 1385 local names 1386 do 1387 local _accum_0 = { } 1388 local _len_0 = 1 1389 for key in pairs(remaining_keys) do 1390 _accum_0[_len_0] = describe_literal(key) 1391 _len_0 = _len_0 + 1 1392 end 1393 names = _accum_0 1394 end 1395 err = "extra fields: " .. tostring(table.concat(names, ", ")) 1396 if check_all then 1397 if errors then 1398 table.insert(errors, err) 1399 else 1400 errors = { 1401 err 1402 } 1403 end 1404 else 1405 return FailedTransform, err 1406 end 1407 end 1408 end 1409 if errors and next(errors) then 1410 return FailedTransform, table.concat(errors, "; ") 1411 end 1412 return dirty and out or value, state 1413 end 1414 } 1415 _base_0.__index = _base_0 1416 setmetatable(_base_0, _parent_0.__base) 1417 _class_0 = setmetatable({ 1418 __init = function(self, shape, opts) 1419 self.shape, self.opts = shape, opts 1420 _class_0.__parent.__init(self) 1421 assert(type(self.shape) == "table", "expected table for shape") 1422 if self.opts then 1423 self.extra_fields_type = self.opts.extra_fields 1424 self.open = self.opts.open 1425 self.check_all = self.opts.check_all 1426 if self.open then 1427 assert(not self.extra_fields_type, "open can not be combined with extra_fields") 1428 end 1429 if self.extra_fields_type then 1430 return assert(not self.open, "extra_fields can not be combined with open") 1431 end 1432 end 1433 end, 1434 __base = _base_0, 1435 __name = "Shape", 1436 __parent = _parent_0 1437 }, { 1438 __index = function(cls, name) 1439 local val = rawget(_base_0, name) 1440 if val == nil then 1441 local parent = rawget(cls, "__parent") 1442 if parent then 1443 return parent[name] 1444 end 1445 else 1446 return val 1447 end 1448 end, 1449 __call = function(cls, ...) 1450 local _self_0 = setmetatable({}, _base_0) 1451 cls.__init(_self_0, ...) 1452 return _self_0 1453 end 1454 }) 1455 _base_0.__class = _class_0 1456 local self = _class_0 1457 self.type_err_message = "expecting table" 1458 if _parent_0.__inherited then 1459 _parent_0.__inherited(_parent_0, _class_0) 1460 end 1461 Shape = _class_0 1462end 1463local Pattern 1464do 1465 local _class_0 1466 local _parent_0 = BaseType 1467 local _base_0 = { 1468 _describe = function(self) 1469 return "pattern " .. tostring(describe_literal(self.pattern)) 1470 end, 1471 _transform = function(self, value, state) 1472 do 1473 local initial = self.opts and self.opts.initial_type 1474 if initial then 1475 if not (type(value) == initial) then 1476 return FailedTransform, "expected " .. tostring(describe_literal(initial)) 1477 end 1478 end 1479 end 1480 if self.opts and self.opts.coerce then 1481 value = tostring(value) 1482 end 1483 local t_res, err = types.string(value) 1484 if not (t_res) then 1485 return FailedTransform, err 1486 end 1487 if value:match(self.pattern) then 1488 return value, state 1489 else 1490 return FailedTransform, "doesn't match " .. tostring(self:_describe()) 1491 end 1492 end 1493 } 1494 _base_0.__index = _base_0 1495 setmetatable(_base_0, _parent_0.__base) 1496 _class_0 = setmetatable({ 1497 __init = function(self, pattern, opts) 1498 self.pattern, self.opts = pattern, opts 1499 return _class_0.__parent.__init(self) 1500 end, 1501 __base = _base_0, 1502 __name = "Pattern", 1503 __parent = _parent_0 1504 }, { 1505 __index = function(cls, name) 1506 local val = rawget(_base_0, name) 1507 if val == nil then 1508 local parent = rawget(cls, "__parent") 1509 if parent then 1510 return parent[name] 1511 end 1512 else 1513 return val 1514 end 1515 end, 1516 __call = function(cls, ...) 1517 local _self_0 = setmetatable({}, _base_0) 1518 cls.__init(_self_0, ...) 1519 return _self_0 1520 end 1521 }) 1522 _base_0.__class = _class_0 1523 if _parent_0.__inherited then 1524 _parent_0.__inherited(_parent_0, _class_0) 1525 end 1526 Pattern = _class_0 1527end 1528local Literal 1529do 1530 local _class_0 1531 local _parent_0 = BaseType 1532 local _base_0 = { 1533 _describe = function(self) 1534 return describe_literal(self.value) 1535 end, 1536 _transform = function(self, value, state) 1537 if self.value ~= value then 1538 return FailedTransform, "expected " .. tostring(self:_describe()) 1539 end 1540 return value, state 1541 end 1542 } 1543 _base_0.__index = _base_0 1544 setmetatable(_base_0, _parent_0.__base) 1545 _class_0 = setmetatable({ 1546 __init = function(self, value, opts) 1547 self.value, self.opts = value, opts 1548 return _class_0.__parent.__init(self) 1549 end, 1550 __base = _base_0, 1551 __name = "Literal", 1552 __parent = _parent_0 1553 }, { 1554 __index = function(cls, name) 1555 local val = rawget(_base_0, name) 1556 if val == nil then 1557 local parent = rawget(cls, "__parent") 1558 if parent then 1559 return parent[name] 1560 end 1561 else 1562 return val 1563 end 1564 end, 1565 __call = function(cls, ...) 1566 local _self_0 = setmetatable({}, _base_0) 1567 cls.__init(_self_0, ...) 1568 return _self_0 1569 end 1570 }) 1571 _base_0.__class = _class_0 1572 if _parent_0.__inherited then 1573 _parent_0.__inherited(_parent_0, _class_0) 1574 end 1575 Literal = _class_0 1576end 1577local Custom 1578do 1579 local _class_0 1580 local _parent_0 = BaseType 1581 local _base_0 = { 1582 _describe = function(self) 1583 return self.opts and self.opts.describe or "custom checker " .. tostring(self.fn) 1584 end, 1585 _transform = function(self, value, state) 1586 local pass, err = self.fn(value, state) 1587 if not (pass) then 1588 return FailedTransform, err or "failed custom check" 1589 end 1590 return value, state 1591 end 1592 } 1593 _base_0.__index = _base_0 1594 setmetatable(_base_0, _parent_0.__base) 1595 _class_0 = setmetatable({ 1596 __init = function(self, fn, opts) 1597 self.fn, self.opts = fn, opts 1598 return _class_0.__parent.__init(self) 1599 end, 1600 __base = _base_0, 1601 __name = "Custom", 1602 __parent = _parent_0 1603 }, { 1604 __index = function(cls, name) 1605 local val = rawget(_base_0, name) 1606 if val == nil then 1607 local parent = rawget(cls, "__parent") 1608 if parent then 1609 return parent[name] 1610 end 1611 else 1612 return val 1613 end 1614 end, 1615 __call = function(cls, ...) 1616 local _self_0 = setmetatable({}, _base_0) 1617 cls.__init(_self_0, ...) 1618 return _self_0 1619 end 1620 }) 1621 _base_0.__class = _class_0 1622 if _parent_0.__inherited then 1623 _parent_0.__inherited(_parent_0, _class_0) 1624 end 1625 Custom = _class_0 1626end 1627local Equivalent 1628do 1629 local _class_0 1630 local values_equivalent 1631 local _parent_0 = BaseType 1632 local _base_0 = { 1633 _transform = function(self, value, state) 1634 if values_equivalent(self.val, value) then 1635 return value, state 1636 else 1637 return FailedTransform, "not equivalent to " .. tostring(self.val) 1638 end 1639 end 1640 } 1641 _base_0.__index = _base_0 1642 setmetatable(_base_0, _parent_0.__base) 1643 _class_0 = setmetatable({ 1644 __init = function(self, val, opts) 1645 self.val, self.opts = val, opts 1646 return _class_0.__parent.__init(self) 1647 end, 1648 __base = _base_0, 1649 __name = "Equivalent", 1650 __parent = _parent_0 1651 }, { 1652 __index = function(cls, name) 1653 local val = rawget(_base_0, name) 1654 if val == nil then 1655 local parent = rawget(cls, "__parent") 1656 if parent then 1657 return parent[name] 1658 end 1659 else 1660 return val 1661 end 1662 end, 1663 __call = function(cls, ...) 1664 local _self_0 = setmetatable({}, _base_0) 1665 cls.__init(_self_0, ...) 1666 return _self_0 1667 end 1668 }) 1669 _base_0.__class = _class_0 1670 local self = _class_0 1671 values_equivalent = function(a, b) 1672 if a == b then 1673 return true 1674 end 1675 if type(a) == "table" and type(b) == "table" then 1676 local seen_keys = { } 1677 for k, v in pairs(a) do 1678 seen_keys[k] = true 1679 if not (values_equivalent(v, b[k])) then 1680 return false 1681 end 1682 end 1683 for k, v in pairs(b) do 1684 local _continue_0 = false 1685 repeat 1686 if seen_keys[k] then 1687 _continue_0 = true 1688 break 1689 end 1690 if not (values_equivalent(v, a[k])) then 1691 return false 1692 end 1693 _continue_0 = true 1694 until true 1695 if not _continue_0 then 1696 break 1697 end 1698 end 1699 return true 1700 else 1701 return false 1702 end 1703 end 1704 if _parent_0.__inherited then 1705 _parent_0.__inherited(_parent_0, _class_0) 1706 end 1707 Equivalent = _class_0 1708end 1709local Range 1710do 1711 local _class_0 1712 local _parent_0 = BaseType 1713 local _base_0 = { 1714 _transform = function(self, value, state) 1715 local res 1716 res, state = self.value_type:_transform(value, state) 1717 if res == FailedTransform then 1718 return FailedTransform, "range " .. tostring(state) 1719 end 1720 if value < self.left then 1721 return FailedTransform, "not in " .. tostring(self:_describe()) 1722 end 1723 if value > self.right then 1724 return FailedTransform, "not in " .. tostring(self:_describe()) 1725 end 1726 return value, state 1727 end, 1728 _describe = function(self) 1729 return "range from " .. tostring(self.left) .. " to " .. tostring(self.right) 1730 end 1731 } 1732 _base_0.__index = _base_0 1733 setmetatable(_base_0, _parent_0.__base) 1734 _class_0 = setmetatable({ 1735 __init = function(self, left, right, opts) 1736 self.left, self.right, self.opts = left, right, opts 1737 _class_0.__parent.__init(self) 1738 assert(self.left <= self.right, "left range value should be less than right range value") 1739 self.value_type = assert(types[type(self.left)], "couldn't figure out type of range boundary") 1740 end, 1741 __base = _base_0, 1742 __name = "Range", 1743 __parent = _parent_0 1744 }, { 1745 __index = function(cls, name) 1746 local val = rawget(_base_0, name) 1747 if val == nil then 1748 local parent = rawget(cls, "__parent") 1749 if parent then 1750 return parent[name] 1751 end 1752 else 1753 return val 1754 end 1755 end, 1756 __call = function(cls, ...) 1757 local _self_0 = setmetatable({}, _base_0) 1758 cls.__init(_self_0, ...) 1759 return _self_0 1760 end 1761 }) 1762 _base_0.__class = _class_0 1763 if _parent_0.__inherited then 1764 _parent_0.__inherited(_parent_0, _class_0) 1765 end 1766 Range = _class_0 1767end 1768local Proxy 1769do 1770 local _class_0 1771 local _parent_0 = BaseType 1772 local _base_0 = { 1773 _transform = function(self, ...) 1774 return assert(self.fn(), "proxy missing transformer"):_transform(...) 1775 end, 1776 _describe = function(self, ...) 1777 return assert(self.fn(), "proxy missing transformer"):_describe(...) 1778 end 1779 } 1780 _base_0.__index = _base_0 1781 setmetatable(_base_0, _parent_0.__base) 1782 _class_0 = setmetatable({ 1783 __init = function(self, fn, opts) 1784 self.fn, self.opts = fn, opts 1785 end, 1786 __base = _base_0, 1787 __name = "Proxy", 1788 __parent = _parent_0 1789 }, { 1790 __index = function(cls, name) 1791 local val = rawget(_base_0, name) 1792 if val == nil then 1793 local parent = rawget(cls, "__parent") 1794 if parent then 1795 return parent[name] 1796 end 1797 else 1798 return val 1799 end 1800 end, 1801 __call = function(cls, ...) 1802 local _self_0 = setmetatable({}, _base_0) 1803 cls.__init(_self_0, ...) 1804 return _self_0 1805 end 1806 }) 1807 _base_0.__class = _class_0 1808 if _parent_0.__inherited then 1809 _parent_0.__inherited(_parent_0, _class_0) 1810 end 1811 Proxy = _class_0 1812end 1813types = setmetatable({ 1814 any = AnyType(), 1815 string = Type("string"), 1816 number = Type("number"), 1817 ["function"] = Type("function"), 1818 func = Type("function"), 1819 boolean = Type("boolean"), 1820 userdata = Type("userdata"), 1821 ["nil"] = Type("nil"), 1822 table = Type("table"), 1823 array = ArrayType(), 1824 integer = Pattern("^%d+$", { 1825 coerce = true, 1826 initial_type = "number" 1827 }), 1828 one_of = OneOf, 1829 all_of = AllOf, 1830 shape = Shape, 1831 pattern = Pattern, 1832 array_of = ArrayOf, 1833 map_of = MapOf, 1834 literal = Literal, 1835 range = Range, 1836 equivalent = Equivalent, 1837 custom = Custom, 1838 scope = TagScopeType, 1839 proxy = Proxy 1840}, { 1841 __index = function(self, fn_name) 1842 return error("Type checker does not exist: `" .. tostring(fn_name) .. "`") 1843 end 1844}) 1845local check_shape 1846check_shape = function(value, shape) 1847 assert(shape.check_value, "missing check_value method from shape") 1848 return shape:check_value(value) 1849end 1850local is_type 1851is_type = function(val) 1852 return BaseType:is_base_type(val) 1853end 1854local type_switch 1855type_switch = function(val) 1856 return setmetatable({ 1857 val 1858 }, { 1859 __eq = BaseType.__eq 1860 }) 1861end 1862return { 1863 check_shape = check_shape, 1864 types = types, 1865 is_type = is_type, 1866 type_switch = type_switch, 1867 BaseType = BaseType, 1868 FailedTransform = FailedTransform, 1869 VERSION = "2.0.0" 1870} 1871