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