Class: Typed::Schema

Inherits:
Object
  • Object
show all
Defined in:
lib/typed/schema.rb

Defined Under Namespace

Classes: Ambiguous, Declared, Explicit, Implicit, LazyValue, Nothing

Constant Summary collapse

NotFound =
Class.new(RuntimeError)

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSchema

Returns a new instance of Schema.



36
37
38
# File 'lib/typed/schema.rb', line 36

def initialize
  @types = ::Hash.new{ Nothing.new }
end

Class Method Details

.declare_method(val) ⇒ Object



26
27
28
29
30
31
32
# File 'lib/typed/schema.rb', line 26

def self.declare_method(val)
  case val
  when LazyValue; val
  when true,false,nil; Ambiguous.new(val)
  else; schema?(val) ? Explicit.new(val) : Implicit.new(val)
  end
end

.schema?(obj) ⇒ Boolean

Returns:



11
12
13
14
15
16
17
# File 'lib/typed/schema.rb', line 11

def self.schema?(obj)
  return true  if obj.is_a?(Class) or obj.is_a?(Module)
  return false if obj == [] or obj == {}
  return schema?(obj.first) if obj.is_a?(Array)
  return obj.first.any?{|i| schema?(i)} if obj.is_a?(::Hash)
  return false
end

.struct(obj) ⇒ Object



19
20
21
22
23
24
# File 'lib/typed/schema.rb', line 19

def self.struct(obj)
  struct = Must::StructInfo.new(obj).compact
  struct = Array  if struct == []
  struct = ::Hash if struct == {}
  return struct
end

Instance Method Details

#[](key) ⇒ Object



44
45
46
# File 'lib/typed/schema.rb', line 44

def [](key)
  @types[key.to_s].value
end

#declare!(key, declare) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/typed/schema.rb', line 52

def declare!(key, declare)
  case declare.must.be.kind_of(Explicit, Implicit)
  when Explicit
    case @types[key.to_s]
    when Explicit
      raise TypeError, "%s has already been declared as `%s'" % [key, @types[key.to_s].value.inspect]
    when Implicit
      type = @types[key.to_s].value
      # update schema if same or sub-class or ancestor, otherwise raises
      declare.value == type            or # need this hack due to bug of Must#struct?
      declare.value.must.struct?(type) or # sub-class
      type.must.struct?(declare.value) or # ancestor
        raise TypeError, "%s has already been typed as `%s'" % [key, @types[key.to_s].value.inspect]
      explicit(key, declare)
    else          
      explicit(key, declare)
    end

  when Implicit
    case @types[key.to_s]
    when Explicit
      # nop
    when Implicit
      # update schema if sub-struct
      struct = self.class.struct(declare.value)
      if struct.must.struct?(@types[key.to_s].value)
        implicit(key, struct)
      end
    else          
      implicit(key, self.class.struct(declare.value))
    end
  end
end

#definition(key) ⇒ Object



40
41
42
# File 'lib/typed/schema.rb', line 40

def definition(key)
  @types[key.to_s]
end

#exist?(key) ⇒ Boolean

Returns:



48
49
50
# File 'lib/typed/schema.rb', line 48

def exist?(key)
  @types.key?(key.to_s)
end

#validate!(key, val, klass) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/typed/schema.rb', line 86

def validate!(key, val, klass)
  return true unless klass
#      raise Schema::NotFound, key.to_s unless klass

  if struct?(val, klass)
    return true 
  else
    expected = klass.inspect
    got      = Must::StructInfo.new(val).compact.inspect
    value    = val.inspect.truncate(200)
    raise TypeError, "%s(%s) got %s: %s" % [key, expected, got, value]
  end
end