Class: Qrb::TypeFactory

Inherits:
Object
  • Object
show all
Defined in:
lib/qrb/support/type_factory.rb

Instance Method Summary collapse

Instance Method Details

#adt(ruby_type, contracts, name = nil) ⇒ Object



113
114
115
116
117
118
119
# File 'lib/qrb/support/type_factory.rb', line 113

def adt(ruby_type, contracts, name = nil)
  ruby_type = ruby_type(ruby_type) if ruby_type
  contracts = contracts(contracts)
  name      = name(name)

  AdType.new(ruby_type, contracts, name)
end

#any(name = nil) ⇒ Object

Type generators



100
101
102
103
104
# File 'lib/qrb/support/type_factory.rb', line 100

def any(name = nil)
  name = name(name)

  AnyType.new(name)
end

#attribute(name, type) ⇒ Object



59
60
61
# File 'lib/qrb/support/type_factory.rb', line 59

def attribute(name, type)
  Attribute.new(name, type(type))
end

#attributes(attributes) ⇒ Object



63
64
65
66
67
68
69
70
71
72
# File 'lib/qrb/support/type_factory.rb', line 63

def attributes(attributes)
  case attributes
  when Hash
    attributes.each_pair.map do |name, type|
      attribute(name, type)
    end
  else
    fail!("Hash expected, got `#{attributes}`")
  end
end

#builtin(ruby_type, name = nil) ⇒ Object



106
107
108
109
110
111
# File 'lib/qrb/support/type_factory.rb', line 106

def builtin(ruby_type, name = nil)
  ruby_type = ruby_type(ruby_type)
  name      = name(name)

  BuiltinType.new(ruby_type, name)
end

#constraints(constraints = nil, &bl) ⇒ Object



51
52
53
54
55
56
57
# File 'lib/qrb/support/type_factory.rb', line 51

def constraints(constraints = nil, &bl)
  constrs = {}
  constrs[:predicate] = bl if bl
  constrs[:predicate] = constraints unless constraints.is_a?(Hash)
  constrs.merge!(constraints)       if constraints.is_a?(Hash)
  constrs
end

#contracts(contracts) ⇒ Object



87
88
89
90
91
92
93
94
95
96
# File 'lib/qrb/support/type_factory.rb', line 87

def contracts(contracts)
  unless contracts.is_a?(Hash)
    fail!("Hash expected, got `#{contracts}`")
  end
  unless (invalid = contracts.keys.reject{|k| k.is_a?(Symbol) }).empty?
    fail!("Invalid contract names `#{invalid}`")
  end

  contracts
end

#heading(heading) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/qrb/support/type_factory.rb', line 74

def heading(heading)
  case heading
  when Heading
    heading
  when TupleType, RelationType
    heading.heading
  when Hash
    Heading.new(attributes(heading))
  else
    fail!("Heading expected, got `#{heading}`")
  end
end

#name(name) ⇒ Object



43
44
45
46
47
48
49
# File 'lib/qrb/support/type_factory.rb', line 43

def name(name)
  unless name.nil? or (name.is_a?(String) and name.strip.size > 1)
    fail!("Wrong type name `#{name}`")
  end

  name.nil? ? nil : name.strip
end

#relation(heading, name = nil) ⇒ Object



170
171
172
173
174
175
# File 'lib/qrb/support/type_factory.rb', line 170

def relation(heading, name = nil)
  heading = heading(heading)
  name    = name(name)

  RelationType.new(heading, name)
end

#ruby_type(type) ⇒ Object

Type Arguments



35
36
37
38
39
40
41
# File 'lib/qrb/support/type_factory.rb', line 35

def ruby_type(type)
  unless type.is_a?(Module)
    fail!("Ruby module expected, got `#{type}`")
  end

  type
end

#seq(elm_type, name = nil) ⇒ Object

Collections



147
148
149
150
151
152
# File 'lib/qrb/support/type_factory.rb', line 147

def seq(elm_type, name = nil)
  elm_type = type(elm_type)
  name     = name(name)

  SeqType.new(elm_type, name)
end

#set(elm_type, name = nil) ⇒ Object



154
155
156
157
158
159
# File 'lib/qrb/support/type_factory.rb', line 154

def set(elm_type, name = nil)
  elm_type = type(elm_type)
  name     = name(name)

  SetType.new(elm_type, name)
end

#subtype(super_type, constraints = nil, name = nil, &bl) ⇒ Object

Sub and union



123
124
125
126
127
128
129
# File 'lib/qrb/support/type_factory.rb', line 123

def subtype(super_type, constraints = nil, name = nil, &bl)
  super_type  = type(super_type)
  constraints = constraints(constraints, &bl)
  name        = name(name)

  SubType.new(super_type, constraints, name)
end

#tuple(heading, name = nil) ⇒ Object

Tuples and relations



163
164
165
166
167
168
# File 'lib/qrb/support/type_factory.rb', line 163

def tuple(heading, name = nil)
  heading = heading(heading)
  name    = name(name)

  TupleType.new(heading, name)
end

#type(type, name = nil, &bl) ⇒ Object

Factory



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/qrb/support/type_factory.rb', line 6

def type(type, name = nil, &bl)
  return subtype(type(type, name), bl) if bl
  case type
  when Type
    type
  when Module
    BuiltinType.new(type, name || type.name.to_s)
  when Hash
    tuple(type, name)
  when Array
    fail!("Array of arity 1 expected, got `#{type}`") unless type.size==1
    seq(type.first, name)
  when Set
    fail!("Set of arity 1 expected, got `#{type}`") unless type.size==1
    sub = type(type.first)
    sub.is_a?(TupleType) ? relation(sub.heading, name) : set(sub, name)
  when Range
    clazz = [type.begin, type.end].map(&:class).uniq
    fail!("Unsupported range `#{type}`") unless clazz.size==1
    subtype(clazz.first, type)
  when Regexp
    subtype(String, type)
  else
    fail!("Unable to factor a Qrb::Type from `#{type}`")
  end
end

#union(*args) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/qrb/support/type_factory.rb', line 131

def union(*args)
  candidates, name = [], nil
  args.each do |arg|
    case arg
    when Array  then candidates = arg.map{|t| type(t) }
    when String then name = name(arg)
    else
      candidates << type(arg)
    end
  end

  UnionType.new(candidates, name)
end