Class: Finitio::TypeFactory

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

Constant Summary collapse

DSL_METHODS =
[
  :attribute,
  :heading,
  :constraint,
  :constraints,
  :contract,
  :contracts,
  :any,
  :builtin,
  :adt,
  :subtype,
  :union,
  :seq,
  :set,
  :struct,
  :tuple,
  :multi_tuple,
  :relation,
  :multi_relation,
  :type,
  :proxy
]

Instance Method Summary collapse

Instance Method Details

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



181
182
183
184
185
186
187
188
# File 'lib/finitio/support/type_factory.rb', line 181

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

  AdType.new(ruby_type, contracts, name, meta)
end

#any(name = nil, metadata = nil) ⇒ Object

Type generators



166
167
168
169
170
171
# File 'lib/finitio/support/type_factory.rb', line 166

def any(name = nil,  = nil)
  name = name(name)
  meta = ()

  AnyType.new(name, meta)
end

#attribute(name, type, required = true, metadata = nil) ⇒ Object



117
118
119
# File 'lib/finitio/support/type_factory.rb', line 117

def attribute(name, type, required = true,  = nil)
  Attribute.new(name, type(type), required, )
end

#attributes(attributes) ⇒ Object



121
122
123
124
125
126
127
128
129
130
# File 'lib/finitio/support/type_factory.rb', line 121

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, metadata = nil) ⇒ Object



173
174
175
176
177
178
179
# File 'lib/finitio/support/type_factory.rb', line 173

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

  BuiltinType.new(ruby_type, name, meta)
end

#constraint(constraint, name = nil) ⇒ Object



92
93
94
95
96
97
# File 'lib/finitio/support/type_factory.rb', line 92

def constraint(constraint, name = nil)
  case constraint
  when Constraint then constraint
  else Constraint.new(constraint, name)
  end
end

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



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/finitio/support/type_factory.rb', line 99

def constraints(constraints = nil, &bl)
  constrs = []
  constrs << Constraint.new(bl) if bl
  case constraints
  when Hash
    constraints.each_pair do |name, cstr|
      constrs << constraint(cstr, name)
    end
  when Array
    constraints.each do |c|
      constrs << constraint(c)
    end
  else
    constrs << Constraint.new(constraints)
  end
  constrs
end

#contract(infotype, dresser, undresser, name = nil, metadata = nil) ⇒ Object



145
146
147
148
# File 'lib/finitio/support/type_factory.rb', line 145

def contract(infotype, dresser, undresser, name = nil,  = nil)
  infotype = type(infotype)
  Contract.new(infotype, dresser, undresser, name, )
end

#contracts(contracts) ⇒ Object



150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/finitio/support/type_factory.rb', line 150

def contracts(contracts)
  case contracts
  when Array
    unless contracts.all?{|c| c.is_a?(Contract) }
      fail!("[Contract] expected, got `#{contracts}`")
    end
    contracts
  when Hash
    contracts.map do |k,v|
      contract(*v.push(k.to_sym))
    end
  end
end

#heading(heading) ⇒ Object



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

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

#metadata(metadata) ⇒ Object



84
85
86
87
88
89
90
# File 'lib/finitio/support/type_factory.rb', line 84

def ()
  unless .nil? or .is_a?(Hash)
    fail!("Wrong metadata `#{}`")
  end

  
end

#multi_relation(heading, name = nil, metadata = nil) ⇒ Object



267
268
269
270
271
272
273
# File 'lib/finitio/support/type_factory.rb', line 267

def multi_relation(heading, name = nil,  = nil)
  heading = heading(heading)
  name    = name(name)
  meta    = ()

  MultiRelationType.new(heading, name, meta)
end

#multi_tuple(heading, name = nil, metadata = nil) ⇒ Object



251
252
253
254
255
256
257
# File 'lib/finitio/support/type_factory.rb', line 251

def multi_tuple(heading, name = nil,  = nil)
  heading = heading(heading)
  name    = name(name)
  meta    = ()

  MultiTupleType.new(heading, name, meta)
end

#name(name) ⇒ Object



76
77
78
79
80
81
82
# File 'lib/finitio/support/type_factory.rb', line 76

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

#proxy(target_name) ⇒ Object



275
276
277
# File 'lib/finitio/support/type_factory.rb', line 275

def proxy(target_name)
  ProxyType.new(target_name)
end

#relation(heading, name = nil, metadata = nil) ⇒ Object



259
260
261
262
263
264
265
# File 'lib/finitio/support/type_factory.rb', line 259

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

  RelationType.new(heading, name, meta)
end

#ruby_type(type) ⇒ Object

Type Arguments



68
69
70
71
72
73
74
# File 'lib/finitio/support/type_factory.rb', line 68

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

  type
end

#seq(elm_type, name = nil, metadata = nil) ⇒ Object

Collections



217
218
219
220
221
222
223
# File 'lib/finitio/support/type_factory.rb', line 217

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

  SeqType.new(elm_type, name, meta)
end

#set(elm_type, name = nil, metadata = nil) ⇒ Object



225
226
227
228
229
230
231
# File 'lib/finitio/support/type_factory.rb', line 225

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

  SetType.new(elm_type, name, meta)
end

#struct(component_types, name = nil, metadata = nil) ⇒ Object



233
234
235
236
237
238
239
# File 'lib/finitio/support/type_factory.rb', line 233

def struct(component_types, name = nil,  = nil)
  component_types = component_types.map{|t| type(t) }
  name            = name(name)
  meta            = ()

  StructType.new(component_types, name, meta)
end

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

Sub and union



192
193
194
195
196
197
198
199
# File 'lib/finitio/support/type_factory.rb', line 192

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

  SubType.new(super_type, constraints, name, )
end

#tuple(heading, name = nil, metadata = nil) ⇒ Object

Tuples and relations



243
244
245
246
247
248
249
# File 'lib/finitio/support/type_factory.rb', line 243

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

  TupleType.new(heading, name, meta)
end

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

Factory



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/finitio/support/type_factory.rb', line 29

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

#union(*args) ⇒ Object



201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/finitio/support/type_factory.rb', line 201

def union(*args)
  candidates, name, meta = [], nil, 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, meta)
end