finitio 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +66 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +34 -30
- data/finitio.gemspec +1 -1
- data/lib/finitio.rb +7 -39
- data/lib/finitio/errors.rb +14 -0
- data/lib/finitio/support.rb +4 -1
- data/lib/finitio/support/attribute.rb +13 -7
- data/lib/finitio/support/compilation.rb +55 -0
- data/lib/finitio/support/constraint.rb +46 -0
- data/lib/finitio/support/contract.rb +33 -0
- data/lib/finitio/support/dress_helper.rb +3 -2
- data/lib/finitio/support/heading.rb +57 -17
- data/lib/finitio/support/metadata.rb +20 -0
- data/lib/finitio/support/type_factory.rb +154 -41
- data/lib/finitio/syntax.rb +16 -31
- data/lib/finitio/syntax/expr.rb +56 -0
- data/lib/finitio/syntax/expr/arith_op.rb +22 -0
- data/lib/finitio/syntax/expr/comparison.rb +22 -0
- data/lib/finitio/syntax/expr/fn_call.rb +24 -0
- data/lib/finitio/syntax/expr/identifier.rb +18 -0
- data/lib/finitio/syntax/expr/literal.rb +19 -0
- data/lib/finitio/syntax/expr/logic_dyadic.rb +22 -0
- data/lib/finitio/syntax/expr/logic_not.rb +21 -0
- data/lib/finitio/syntax/expr/oo_call.rb +24 -0
- data/lib/finitio/syntax/expr/parenthesized.rb +20 -0
- data/lib/finitio/syntax/expr/unary_minus_op.rb +21 -0
- data/lib/finitio/syntax/expressions.citrus +129 -0
- data/lib/finitio/syntax/finitio.citrus +10 -208
- data/lib/finitio/syntax/finitio.sexp +5 -1
- data/lib/finitio/syntax/lexer.citrus +91 -0
- data/lib/finitio/syntax/literal.rb +16 -0
- data/lib/finitio/syntax/literal/boolean.rb +22 -0
- data/lib/finitio/syntax/literal/integer.rb +14 -0
- data/lib/finitio/syntax/literal/real.rb +14 -0
- data/lib/finitio/syntax/literal/string.rb +14 -0
- data/lib/finitio/syntax/literals.citrus +44 -0
- data/lib/finitio/syntax/node.rb +53 -0
- data/lib/finitio/syntax/type.rb +28 -0
- data/lib/finitio/syntax/type/ad_type.rb +29 -0
- data/lib/finitio/syntax/{any_type.rb → type/any_type.rb} +1 -1
- data/lib/finitio/syntax/type/attribute.rb +33 -0
- data/lib/finitio/syntax/{builtin_type.rb → type/builtin_type.rb} +3 -1
- data/lib/finitio/syntax/{constraint_def.rb → type/constraint_def.rb} +4 -3
- data/lib/finitio/syntax/type/constraints.rb +17 -0
- data/lib/finitio/syntax/{contract.rb → type/contract.rb} +9 -3
- data/lib/finitio/syntax/{definitions.rb → type/definitions.rb} +1 -0
- data/lib/finitio/syntax/{expression.rb → type/expression.rb} +2 -1
- data/lib/finitio/syntax/{external_pair.rb → type/external_pair.rb} +3 -1
- data/lib/finitio/syntax/type/heading.rb +30 -0
- data/lib/finitio/syntax/{inline_pair.rb → type/inline_pair.rb} +3 -1
- data/lib/finitio/syntax/{lambda_expr.rb → type/lambda_expr.rb} +3 -0
- data/lib/finitio/syntax/type/main_type.rb +18 -0
- data/lib/finitio/syntax/type/metadata.rb +18 -0
- data/lib/finitio/syntax/type/metadata_attr.rb +15 -0
- data/lib/finitio/syntax/{named_constraint.rb → type/named_constraint.rb} +10 -3
- data/lib/finitio/syntax/type/relation_type.rb +24 -0
- data/lib/finitio/syntax/{seq_type.rb → type/seq_type.rb} +3 -0
- data/lib/finitio/syntax/{set_type.rb → type/set_type.rb} +3 -0
- data/lib/finitio/syntax/type/struct_type.rb +17 -0
- data/lib/finitio/syntax/{sub_type.rb → type/sub_type.rb} +3 -0
- data/lib/finitio/syntax/{system.rb → type/system.rb} +5 -4
- data/lib/finitio/syntax/type/tuple_type.rb +24 -0
- data/lib/finitio/syntax/{type_def.rb → type/type_def.rb} +8 -3
- data/lib/finitio/syntax/{type_ref.rb → type/type_ref.rb} +4 -1
- data/lib/finitio/syntax/{union_type.rb → type/union_type.rb} +1 -0
- data/lib/finitio/syntax/{unnamed_constraint.rb → type/unnamed_constraint.rb} +7 -1
- data/lib/finitio/syntax/types.citrus +196 -0
- data/lib/finitio/system.rb +15 -15
- data/lib/finitio/type.rb +38 -6
- data/lib/finitio/type/ad_type.rb +41 -18
- data/lib/finitio/type/alias_type.rb +37 -0
- data/lib/finitio/type/any_type.rb +7 -3
- data/lib/finitio/type/builtin_type.rb +5 -4
- data/lib/finitio/{support → type}/collection_type.rb +3 -4
- data/lib/finitio/type/hash_based_type.rb +91 -0
- data/lib/finitio/type/heading_based_type.rb +28 -0
- data/lib/finitio/type/multi_relation_type.rb +34 -0
- data/lib/finitio/type/multi_tuple_type.rb +29 -0
- data/lib/finitio/type/proxy_type.rb +40 -0
- data/lib/finitio/type/rel_based_type.rb +42 -0
- data/lib/finitio/type/relation_type.rb +6 -47
- data/lib/finitio/type/seq_type.rb +4 -0
- data/lib/finitio/type/set_type.rb +4 -0
- data/lib/finitio/type/struct_type.rb +84 -0
- data/lib/finitio/type/sub_type.rb +25 -22
- data/lib/finitio/type/tuple_type.rb +6 -57
- data/lib/finitio/type/union_type.rb +12 -5
- data/lib/finitio/version.rb +2 -2
- data/spec/{unit/attribute → attribute}/test_equality.rb +8 -5
- data/spec/{unit/attribute → attribute}/test_fetch_on.rb +5 -5
- data/spec/attribute/test_initialize.rb +26 -0
- data/spec/attribute/test_optional.rb +18 -0
- data/spec/attribute/test_required.rb +18 -0
- data/spec/attribute/test_to_name.rb +20 -0
- data/spec/constraint/test_anonymous.rb +20 -0
- data/spec/constraint/test_equality.rb +39 -0
- data/spec/constraint/test_name.rb +20 -0
- data/spec/constraint/test_named.rb +20 -0
- data/spec/constraint/test_triple_equal.rb +13 -0
- data/spec/{unit/qrb/system.q → finitio/system.fio} +0 -0
- data/spec/{unit/qrb → finitio}/test_ast.rb +0 -0
- data/spec/finitio/test_parse.rb +23 -0
- data/spec/{unit/qrb/test_parse.rb → finitio/test_system.rb} +6 -6
- data/spec/heading/test_allow_extra.rb +24 -0
- data/spec/{unit/heading → heading}/test_each.rb +2 -2
- data/spec/heading/test_equality.rb +38 -0
- data/spec/heading/test_hash.rb +38 -0
- data/spec/heading/test_hash_get.rb +17 -0
- data/spec/{unit/heading → heading}/test_initialize.rb +2 -2
- data/spec/heading/test_multi.rb +57 -0
- data/spec/{unit/heading → heading}/test_size.rb +0 -0
- data/spec/heading/test_to_name.rb +58 -0
- data/spec/spec_helper.rb +17 -1
- data/spec/syntax/expr/test_free_variables.rb +46 -0
- data/spec/syntax/expr/test_to_proc_source.rb +43 -0
- data/spec/{unit/syntax → syntax}/nodes/test_ad_type.rb +26 -26
- data/spec/{unit/syntax → syntax}/nodes/test_any_type.rb +2 -2
- data/spec/syntax/nodes/test_attribute.rb +65 -0
- data/spec/{unit/syntax → syntax}/nodes/test_builtin_type.rb +5 -5
- data/spec/{unit/syntax → syntax}/nodes/test_comment.rb +1 -1
- data/spec/{unit/syntax → syntax}/nodes/test_constraint_def.rb +3 -8
- data/spec/{unit/syntax → syntax}/nodes/test_constraints.rb +21 -16
- data/spec/{unit/syntax → syntax}/nodes/test_contract.rb +28 -35
- data/spec/{unit/syntax → syntax}/nodes/test_expression.rb +13 -5
- data/spec/{unit/syntax → syntax}/nodes/test_heading.rb +25 -7
- data/spec/syntax/nodes/test_metadata.rb +28 -0
- data/spec/{unit/syntax → syntax}/nodes/test_named_constraint.rb +8 -8
- data/spec/syntax/nodes/test_relation_type.rb +84 -0
- data/spec/{unit/syntax → syntax}/nodes/test_seq_type.rb +4 -4
- data/spec/{unit/syntax → syntax}/nodes/test_set_type.rb +4 -4
- data/spec/{unit/syntax → syntax}/nodes/test_spacing.rb +1 -1
- data/spec/syntax/nodes/test_struct_type.rb +38 -0
- data/spec/{unit/syntax → syntax}/nodes/test_sub_type.rb +14 -14
- data/spec/{unit/syntax → syntax}/nodes/test_system.rb +3 -3
- data/spec/syntax/nodes/test_tuple_type.rb +94 -0
- data/spec/syntax/nodes/test_type_def.rb +57 -0
- data/spec/{unit/syntax → syntax}/nodes/test_type_ref.rb +3 -3
- data/spec/{unit/syntax → syntax}/nodes/test_union_type.rb +3 -3
- data/spec/{unit/syntax → syntax}/nodes/test_unnamed_constraint.rb +7 -7
- data/spec/syntax/test_compile.rb +41 -0
- data/spec/{unit/syntax → syntax}/test_compile_type.rb +1 -1
- data/spec/{unit/system → system}/test_add_type.rb +6 -6
- data/spec/{unit/system → system}/test_dsl.rb +2 -2
- data/spec/{unit/system → system}/test_dup.rb +4 -4
- data/spec/{unit/system → system}/test_fetch.rb +4 -4
- data/spec/{unit/system → system}/test_get_type.rb +2 -2
- data/spec/{unit/system → system}/test_initialize.rb +0 -0
- data/spec/test_finitio.rb +8 -0
- data/spec/{unit/type → type}/ad_type/test_default_name.rb +1 -2
- data/spec/{unit/type → type}/ad_type/test_dress.rb +19 -9
- data/spec/{unit/type → type}/ad_type/test_include.rb +3 -3
- data/spec/{unit/type → type}/ad_type/test_initialize.rb +15 -8
- data/spec/{unit/type → type}/ad_type/test_name.rb +2 -2
- data/spec/type/alias_type/test_default_name.rb +10 -0
- data/spec/type/alias_type/test_delegation.rb +29 -0
- data/spec/type/alias_type/test_name.rb +10 -0
- data/spec/{unit/type → type}/any_type/test_default_name.rb +1 -1
- data/spec/{unit/type → type}/any_type/test_dress.rb +0 -0
- data/spec/{unit/type → type}/any_type/test_equality.rb +4 -4
- data/spec/{unit/type → type}/any_type/test_include.rb +2 -2
- data/spec/{unit/type → type}/any_type/test_initialize.rb +0 -0
- data/spec/{unit/type → type}/any_type/test_name.rb +2 -2
- data/spec/{unit/type → type}/builtin_type/test_default_name.rb +1 -1
- data/spec/{unit/type → type}/builtin_type/test_dress.rb +3 -3
- data/spec/{unit/type → type}/builtin_type/test_equality.rb +4 -4
- data/spec/{unit/type → type}/builtin_type/test_include.rb +2 -2
- data/spec/{unit/type → type}/builtin_type/test_initialize.rb +1 -1
- data/spec/{unit/type → type}/builtin_type/test_name.rb +2 -2
- data/spec/type/multi_relation_type/test_default_name.rb +19 -0
- data/spec/type/multi_relation_type/test_dress.rb +206 -0
- data/spec/type/multi_relation_type/test_equality.rb +36 -0
- data/spec/type/multi_relation_type/test_include.rb +89 -0
- data/spec/type/multi_relation_type/test_initialize.rb +29 -0
- data/spec/type/multi_relation_type/test_name.rb +27 -0
- data/spec/type/multi_tuple_type/test_default_name.rb +17 -0
- data/spec/type/multi_tuple_type/test_dress.rb +146 -0
- data/spec/type/multi_tuple_type/test_equality.rb +32 -0
- data/spec/type/multi_tuple_type/test_include.rb +73 -0
- data/spec/type/multi_tuple_type/test_initialize.rb +30 -0
- data/spec/type/multi_tuple_type/test_name.rb +24 -0
- data/spec/type/proxy_type/test_delegation.rb +37 -0
- data/spec/type/proxy_type/test_resolve.rb +29 -0
- data/spec/{unit/type → type}/relation_type/test_default_name.rb +0 -0
- data/spec/{unit/type → type}/relation_type/test_dress.rb +24 -24
- data/spec/{unit/type → type}/relation_type/test_equality.rb +6 -6
- data/spec/{unit/type → type}/relation_type/test_include.rb +4 -4
- data/spec/{unit/type → type}/relation_type/test_initialize.rb +2 -2
- data/spec/{unit/type → type}/relation_type/test_name.rb +0 -0
- data/spec/{unit/type → type}/seq_type/test_default_name.rb +0 -0
- data/spec/{unit/type → type}/seq_type/test_dress.rb +5 -5
- data/spec/{unit/type → type}/seq_type/test_equality.rb +4 -4
- data/spec/{unit/type → type}/seq_type/test_include.rb +4 -4
- data/spec/{unit/type → type}/seq_type/test_initialize.rb +3 -3
- data/spec/{unit/type → type}/seq_type/test_name.rb +0 -0
- data/spec/{unit/type → type}/set_type/test_default_name.rb +0 -0
- data/spec/{unit/type → type}/set_type/test_dress.rb +8 -8
- data/spec/{unit/type → type}/set_type/test_equality.rb +4 -4
- data/spec/{unit/type → type}/set_type/test_include.rb +4 -4
- data/spec/{unit/type → type}/set_type/test_initialize.rb +3 -3
- data/spec/{unit/type → type}/set_type/test_name.rb +0 -0
- data/spec/type/struct_type/test_default_name.rb +10 -0
- data/spec/type/struct_type/test_dress.rb +105 -0
- data/spec/type/struct_type/test_equality.rb +28 -0
- data/spec/type/struct_type/test_include.rb +40 -0
- data/spec/type/struct_type/test_initialize.rb +22 -0
- data/spec/type/struct_type/test_name.rb +20 -0
- data/spec/{unit/type → type}/sub_type/test_default_name.rb +2 -2
- data/spec/{unit/type → type}/sub_type/test_dress.rb +14 -14
- data/spec/type/sub_type/test_equality.rb +46 -0
- data/spec/{unit/type → type}/sub_type/test_include.rb +6 -6
- data/spec/type/sub_type/test_initialize.rb +13 -0
- data/spec/{unit/type → type}/sub_type/test_name.rb +4 -4
- data/spec/{unit/type → type}/tuple_type/test_default_name.rb +0 -0
- data/spec/{unit/type → type}/tuple_type/test_dress.rb +18 -18
- data/spec/{unit/type → type}/tuple_type/test_equality.rb +6 -6
- data/spec/{unit/type → type}/tuple_type/test_include.rb +4 -4
- data/spec/{unit/type → type}/tuple_type/test_initialize.rb +4 -4
- data/spec/{unit/type → type}/tuple_type/test_name.rb +0 -0
- data/spec/{unit/type → type}/union_type/test_default_name.rb +0 -0
- data/spec/{unit/type → type}/union_type/test_dress.rb +7 -6
- data/spec/{unit/type → type}/union_type/test_equality.rb +7 -7
- data/spec/{unit/type → type}/union_type/test_include.rb +3 -3
- data/spec/{unit/type → type}/union_type/test_initialize.rb +3 -3
- data/spec/{unit/type → type}/union_type/test_name.rb +0 -0
- data/spec/{unit/type_factory → type_factory}/dsl/test_adt.rb +4 -4
- data/spec/{unit/type_factory → type_factory}/dsl/test_any.rb +1 -1
- data/spec/{unit/type_factory → type_factory}/dsl/test_attribute.rb +16 -2
- data/spec/{unit/type_factory → type_factory}/dsl/test_attributes.rb +1 -1
- data/spec/{unit/type_factory → type_factory}/dsl/test_builtin.rb +3 -3
- data/spec/type_factory/dsl/test_multi_relation.rb +39 -0
- data/spec/type_factory/dsl/test_multi_tuple.rb +37 -0
- data/spec/{unit/type_factory → type_factory}/dsl/test_relation.rb +6 -6
- data/spec/{unit/type_factory → type_factory}/dsl/test_seq.rb +4 -4
- data/spec/{unit/type_factory → type_factory}/dsl/test_set.rb +4 -4
- data/spec/type_factory/dsl/test_struct.rb +45 -0
- data/spec/{unit/type_factory → type_factory}/dsl/test_subtype.rb +10 -8
- data/spec/{unit/type_factory → type_factory}/dsl/test_tuple.rb +5 -5
- data/spec/{unit/type_factory → type_factory}/dsl/test_union.rb +6 -6
- data/spec/{unit/type_factory → type_factory}/factory/test_builtin.rb +1 -1
- data/spec/{unit/type_factory → type_factory}/factory/test_seq_type.rb +2 -2
- data/spec/{unit/type_factory → type_factory}/factory/test_set_type.rb +2 -2
- data/spec/type_factory/factory/test_struct_type.rb +18 -0
- data/spec/{unit/type_factory → type_factory}/factory/test_sub_type.rb +7 -7
- data/spec/{unit/type_factory → type_factory}/factory/test_tuple_type.rb +4 -4
- metadata +398 -286
- data/lib/finitio/data_type.rb +0 -29
- data/lib/finitio/syntax/ad_type.rb +0 -32
- data/lib/finitio/syntax/attribute.rb +0 -15
- data/lib/finitio/syntax/constraints.rb +0 -22
- data/lib/finitio/syntax/heading.rb +0 -19
- data/lib/finitio/syntax/relation_type.rb +0 -15
- data/lib/finitio/syntax/support.rb +0 -13
- data/lib/finitio/syntax/tuple_type.rb +0 -15
- data/spec/acceptance/Finitio/test_default.rb +0 -96
- data/spec/acceptance/Finitio/test_parsing.rb +0 -15
- data/spec/acceptance/ad_type/test_in_finitio.rb +0 -82
- data/spec/acceptance/ad_type/test_in_ruby.rb +0 -60
- data/spec/unit/attribute/test_initialize.rb +0 -13
- data/spec/unit/attribute/test_to_name.rb +0 -10
- data/spec/unit/heading/test_equality.rb +0 -28
- data/spec/unit/heading/test_to_name.rb +0 -32
- data/spec/unit/syntax/nodes/test_attribute.rb +0 -38
- data/spec/unit/syntax/nodes/test_relation_type.rb +0 -59
- data/spec/unit/syntax/nodes/test_tuple_type.rb +0 -59
- data/spec/unit/syntax/nodes/test_type_def.rb +0 -33
- data/spec/unit/test_finitio.rb +0 -15
- data/spec/unit/type/sub_type/test_equality.rb +0 -34
- data/spec/unit/type/sub_type/test_initialize.rb +0 -16
@@ -0,0 +1,33 @@
|
|
1
|
+
module Finitio
|
2
|
+
class Contract
|
3
|
+
include Metadata
|
4
|
+
|
5
|
+
def initialize(infotype, dresser, undresser, name = nil, metadata = nil)
|
6
|
+
unless infotype.is_a?(Type)
|
7
|
+
raise ArgumentError, "Type expected, got `#{infotype}`"
|
8
|
+
end
|
9
|
+
unless dresser.respond_to?(:call)
|
10
|
+
raise ArgumentError, "r(:call) expected, got `#{dresser}`"
|
11
|
+
end
|
12
|
+
unless undresser.respond_to?(:call)
|
13
|
+
raise ArgumentError, "r(:call) expected, got `#{undresser}`"
|
14
|
+
end
|
15
|
+
unless name.nil? or name.is_a?(Symbol)
|
16
|
+
raise ArgumentError, "Symbol expected, got `#{name}`"
|
17
|
+
end
|
18
|
+
|
19
|
+
@name = name
|
20
|
+
@infotype = infotype
|
21
|
+
@dresser = dresser
|
22
|
+
@undresser = undresser
|
23
|
+
@metadata = metadata
|
24
|
+
end
|
25
|
+
attr_reader :name, :infotype, :dresser, :undresser
|
26
|
+
|
27
|
+
def bind_ruby_type(clazz)
|
28
|
+
@dresser = clazz.method(name.to_sym)
|
29
|
+
@undresser = clazz.instance_method(:"to_#{name}")
|
30
|
+
end
|
31
|
+
|
32
|
+
end # class Contract
|
33
|
+
end # module Finitio
|
@@ -24,7 +24,8 @@ module Finitio
|
|
24
24
|
def just_try(rescue_on = TypeError)
|
25
25
|
[ true, yield ]
|
26
26
|
rescue rescue_on => cause
|
27
|
-
|
27
|
+
#STDERR.puts cause.inspect
|
28
|
+
[ false, cause ]
|
28
29
|
end
|
29
30
|
|
30
31
|
def try(type, value)
|
@@ -44,7 +45,7 @@ module Finitio
|
|
44
45
|
|
45
46
|
def default_error_message(type, value)
|
46
47
|
value_s, type_s = value_to_s(value), type_to_s(type)
|
47
|
-
"Invalid
|
48
|
+
"Invalid #{type_s} `#{value_s}`"
|
48
49
|
end
|
49
50
|
|
50
51
|
def location
|
@@ -8,20 +8,21 @@ module Finitio
|
|
8
8
|
class Heading
|
9
9
|
include Enumerable
|
10
10
|
|
11
|
-
|
12
|
-
unless attributes.is_a?(Enumerable) and \
|
13
|
-
attributes.all?{|a| a.is_a?(Attribute) }
|
14
|
-
raise ArgumentError, "Enumerable[Attribute] expected"
|
15
|
-
end
|
11
|
+
DEFAULT_OPTIONS = { allow_extra: false }.freeze
|
16
12
|
|
17
|
-
|
18
|
-
attributes
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
13
|
+
def initialize(attributes, options = nil)
|
14
|
+
@attributes = normalize_attributes(attributes)
|
15
|
+
@options = normalize_options(options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def [](attrname)
|
19
|
+
@attributes[attrname]
|
20
|
+
end
|
21
|
+
|
22
|
+
def fetch(attrname)
|
23
|
+
@attributes.fetch(attrname) do
|
24
|
+
raise Error, "No such attribute `#{attrname}`"
|
23
25
|
end
|
24
|
-
@attributes.freeze
|
25
26
|
end
|
26
27
|
|
27
28
|
def size
|
@@ -32,26 +33,65 @@ module Finitio
|
|
32
33
|
size == 0
|
33
34
|
end
|
34
35
|
|
36
|
+
def multi?
|
37
|
+
allow_extra? || any?{|attr| not(attr.required?) }
|
38
|
+
end
|
39
|
+
|
40
|
+
def allow_extra?
|
41
|
+
options[:allow_extra]
|
42
|
+
end
|
43
|
+
|
35
44
|
def each(&bl)
|
36
45
|
return to_enum unless bl
|
37
46
|
@attributes.values.each(&bl)
|
38
47
|
end
|
39
48
|
|
40
49
|
def to_name
|
41
|
-
map(&:to_name).join(', ')
|
50
|
+
name = map(&:to_name).join(', ')
|
51
|
+
if allow_extra?
|
52
|
+
name << ", " unless empty?
|
53
|
+
name << "..."
|
54
|
+
end
|
55
|
+
name
|
42
56
|
end
|
43
57
|
|
44
58
|
def ==(other)
|
45
59
|
return nil unless other.is_a?(Heading)
|
46
|
-
attributes == other.attributes
|
60
|
+
attributes == other.attributes && options == other.options
|
47
61
|
end
|
48
62
|
|
49
63
|
def hash
|
50
|
-
self.class.hash ^ attributes.hash
|
64
|
+
self.class.hash ^ attributes.hash ^ options.hash
|
51
65
|
end
|
52
66
|
|
53
|
-
attr_reader :attributes
|
54
|
-
protected :attributes
|
67
|
+
attr_reader :attributes, :options
|
68
|
+
protected :attributes, :options
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def normalize_attributes(attrs)
|
73
|
+
unless attrs.respond_to?(:each)
|
74
|
+
raise ArgumentError, "Enumerable[Attribute] expected"
|
75
|
+
end
|
76
|
+
|
77
|
+
attributes = {}
|
78
|
+
attrs.each do |attr|
|
79
|
+
unless attr.is_a?(Attribute)
|
80
|
+
raise ArgumentError, "Enumerable[Attribute] expected"
|
81
|
+
end
|
82
|
+
if attributes[attr.name]
|
83
|
+
raise ArgumentError, "Attribute names must be unique"
|
84
|
+
end
|
85
|
+
attributes[attr.name] = attr
|
86
|
+
end
|
87
|
+
attributes.freeze
|
88
|
+
end
|
89
|
+
|
90
|
+
def normalize_options(opts)
|
91
|
+
options = DEFAULT_OPTIONS
|
92
|
+
options = options.merge(opts).freeze if opts
|
93
|
+
options
|
94
|
+
end
|
55
95
|
|
56
96
|
end # class Heading
|
57
97
|
end # class Finitio
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Finitio
|
2
|
+
module Metadata
|
3
|
+
|
4
|
+
EMPTY_METADATA = {}.freeze
|
5
|
+
|
6
|
+
def metadata
|
7
|
+
@metadata || EMPTY_METADATA
|
8
|
+
end
|
9
|
+
|
10
|
+
def metadata?
|
11
|
+
!@metadata.nil?
|
12
|
+
end
|
13
|
+
|
14
|
+
def metadata=(hash)
|
15
|
+
raise "Metadata already set to #{@metadata.inspect}" unless @metadata.nil?
|
16
|
+
@metadata = hash
|
17
|
+
end
|
18
|
+
|
19
|
+
end # module Metadata
|
20
|
+
end # module Finitio
|
@@ -1,30 +1,63 @@
|
|
1
1
|
module Finitio
|
2
2
|
class TypeFactory
|
3
3
|
|
4
|
+
DSL_METHODS = [
|
5
|
+
:attribute,
|
6
|
+
:heading,
|
7
|
+
:constraint,
|
8
|
+
:constraints,
|
9
|
+
:contract,
|
10
|
+
:contracts,
|
11
|
+
:any,
|
12
|
+
:builtin,
|
13
|
+
:adt,
|
14
|
+
:subtype,
|
15
|
+
:union,
|
16
|
+
:seq,
|
17
|
+
:set,
|
18
|
+
:struct,
|
19
|
+
:tuple,
|
20
|
+
:multi_tuple,
|
21
|
+
:relation,
|
22
|
+
:multi_relation,
|
23
|
+
:type,
|
24
|
+
:proxy
|
25
|
+
]
|
26
|
+
|
4
27
|
################################################################## Factory
|
5
28
|
|
6
|
-
def type(type, name = nil, &bl)
|
7
|
-
return subtype(type(type, name), bl) if bl
|
29
|
+
def type(type, name = nil, metadata = nil, &bl)
|
30
|
+
return subtype(type(type, name, metadata), bl) if bl
|
8
31
|
case type
|
9
32
|
when Type
|
10
|
-
type
|
33
|
+
alias_type(type, name, metadata)
|
11
34
|
when Module
|
12
|
-
BuiltinType.new(type, name || type.name.to_s)
|
35
|
+
BuiltinType.new(type, name || type.name.to_s, metadata)
|
13
36
|
when Hash
|
14
|
-
tuple(type, name)
|
37
|
+
tuple(type, name, metadata)
|
15
38
|
when Array
|
16
|
-
|
17
|
-
|
39
|
+
case type.size
|
40
|
+
when 0
|
41
|
+
fail!("Array of arity > 0 expected, got `#{type}`")
|
42
|
+
when 1
|
43
|
+
seq(type.first, name, metadata)
|
44
|
+
else
|
45
|
+
struct(type, name, metadata)
|
46
|
+
end
|
18
47
|
when Set
|
19
48
|
fail!("Set of arity 1 expected, got `#{type}`") unless type.size==1
|
20
49
|
sub = type(type.first)
|
21
|
-
sub.is_a?(TupleType)
|
50
|
+
if sub.is_a?(TupleType)
|
51
|
+
relation(sub.heading, name, metadata)
|
52
|
+
else
|
53
|
+
set(sub, name, metadata)
|
54
|
+
end
|
22
55
|
when Range
|
23
56
|
clazz = [type.begin, type.end].map(&:class).uniq
|
24
57
|
fail!("Unsupported range `#{type}`") unless clazz.size==1
|
25
|
-
subtype(clazz.first, type)
|
58
|
+
subtype(clazz.first, type, name, metadata)
|
26
59
|
when Regexp
|
27
|
-
subtype(String, type)
|
60
|
+
subtype(String, type, name, metadata)
|
28
61
|
else
|
29
62
|
fail!("Unable to factor a Finitio::Type from `#{type}`")
|
30
63
|
end
|
@@ -48,16 +81,41 @@ module Finitio
|
|
48
81
|
name.nil? ? nil : name.strip
|
49
82
|
end
|
50
83
|
|
84
|
+
def metadata(metadata)
|
85
|
+
unless metadata.nil? or metadata.is_a?(Hash)
|
86
|
+
fail!("Wrong metadata `#{metadata}`")
|
87
|
+
end
|
88
|
+
|
89
|
+
metadata
|
90
|
+
end
|
91
|
+
|
92
|
+
def constraint(constraint, name = nil)
|
93
|
+
case constraint
|
94
|
+
when Constraint then constraint
|
95
|
+
else Constraint.new(constraint, name)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
51
99
|
def constraints(constraints = nil, &bl)
|
52
|
-
constrs =
|
53
|
-
constrs
|
54
|
-
|
55
|
-
|
100
|
+
constrs = []
|
101
|
+
constrs << Constraint.new(bl) if bl
|
102
|
+
case constraints
|
103
|
+
when Hash
|
104
|
+
constraints.each_pair do |name, cstr|
|
105
|
+
constrs << constraint(cstr, name)
|
106
|
+
end
|
107
|
+
when Array
|
108
|
+
constraints.each do |c|
|
109
|
+
constrs << constraint(c)
|
110
|
+
end
|
111
|
+
else
|
112
|
+
constrs << Constraint.new(constraints)
|
113
|
+
end
|
56
114
|
constrs
|
57
115
|
end
|
58
116
|
|
59
|
-
def attribute(name, type)
|
60
|
-
Attribute.new(name, type(type))
|
117
|
+
def attribute(name, type, required = true, metadata = nil)
|
118
|
+
Attribute.new(name, type(type), required, metadata)
|
61
119
|
end
|
62
120
|
|
63
121
|
def attributes(attributes)
|
@@ -84,52 +142,64 @@ module Finitio
|
|
84
142
|
end
|
85
143
|
end
|
86
144
|
|
145
|
+
def contract(infotype, dresser, undresser, name = nil, metadata = nil)
|
146
|
+
infotype = type(infotype)
|
147
|
+
Contract.new(infotype, dresser, undresser, name, metadata)
|
148
|
+
end
|
149
|
+
|
87
150
|
def contracts(contracts)
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
151
|
+
case contracts
|
152
|
+
when Array
|
153
|
+
unless contracts.all?{|c| c.is_a?(Contract) }
|
154
|
+
fail!("[Contract] expected, got `#{contracts}`")
|
155
|
+
end
|
156
|
+
contracts
|
157
|
+
when Hash
|
158
|
+
contracts.map do |k,v|
|
159
|
+
contract(*v.push(k.to_sym))
|
160
|
+
end
|
93
161
|
end
|
94
|
-
|
95
|
-
contracts
|
96
162
|
end
|
97
163
|
|
98
164
|
########################################################## Type generators
|
99
165
|
|
100
|
-
def any(name = nil)
|
166
|
+
def any(name = nil, metadata = nil)
|
101
167
|
name = name(name)
|
168
|
+
meta = metadata(metadata)
|
102
169
|
|
103
|
-
AnyType.new(name)
|
170
|
+
AnyType.new(name, meta)
|
104
171
|
end
|
105
172
|
|
106
|
-
def builtin(ruby_type, name = nil)
|
173
|
+
def builtin(ruby_type, name = nil, metadata = nil)
|
107
174
|
ruby_type = ruby_type(ruby_type)
|
108
175
|
name = name(name)
|
176
|
+
meta = metadata(metadata)
|
109
177
|
|
110
|
-
BuiltinType.new(ruby_type, name)
|
178
|
+
BuiltinType.new(ruby_type, name, meta)
|
111
179
|
end
|
112
180
|
|
113
|
-
def adt(ruby_type, contracts, name = nil)
|
181
|
+
def adt(ruby_type, contracts, name = nil, metadata = nil)
|
114
182
|
ruby_type = ruby_type(ruby_type) if ruby_type
|
115
183
|
contracts = contracts(contracts)
|
116
184
|
name = name(name)
|
185
|
+
meta = metadata(metadata)
|
117
186
|
|
118
|
-
AdType.new(ruby_type, contracts, name)
|
187
|
+
AdType.new(ruby_type, contracts, name, meta)
|
119
188
|
end
|
120
189
|
|
121
190
|
### Sub and union
|
122
191
|
|
123
|
-
def subtype(super_type, constraints = nil, name = nil, &bl)
|
192
|
+
def subtype(super_type, constraints = nil, name = nil, metadata = nil, &bl)
|
124
193
|
super_type = type(super_type)
|
125
194
|
constraints = constraints(constraints, &bl)
|
126
195
|
name = name(name)
|
196
|
+
meta = metadata(metadata)
|
127
197
|
|
128
|
-
SubType.new(super_type, constraints, name)
|
198
|
+
SubType.new(super_type, constraints, name, metadata)
|
129
199
|
end
|
130
200
|
|
131
201
|
def union(*args)
|
132
|
-
candidates, name = [], nil
|
202
|
+
candidates, name, meta = [], nil, nil
|
133
203
|
args.each do |arg|
|
134
204
|
case arg
|
135
205
|
when Array then candidates = arg.map{|t| type(t) }
|
@@ -139,43 +209,86 @@ module Finitio
|
|
139
209
|
end
|
140
210
|
end
|
141
211
|
|
142
|
-
UnionType.new(candidates, name)
|
212
|
+
UnionType.new(candidates, name, meta)
|
143
213
|
end
|
144
214
|
|
145
215
|
### Collections
|
146
216
|
|
147
|
-
def seq(elm_type, name = nil)
|
217
|
+
def seq(elm_type, name = nil, metadata = nil)
|
148
218
|
elm_type = type(elm_type)
|
149
219
|
name = name(name)
|
220
|
+
meta = metadata(metadata)
|
150
221
|
|
151
|
-
SeqType.new(elm_type, name)
|
222
|
+
SeqType.new(elm_type, name, meta)
|
152
223
|
end
|
153
224
|
|
154
|
-
def set(elm_type, name = nil)
|
225
|
+
def set(elm_type, name = nil, metadata = nil)
|
155
226
|
elm_type = type(elm_type)
|
156
227
|
name = name(name)
|
228
|
+
meta = metadata(metadata)
|
229
|
+
|
230
|
+
SetType.new(elm_type, name, meta)
|
231
|
+
end
|
232
|
+
|
233
|
+
def struct(component_types, name = nil, metadata = nil)
|
234
|
+
component_types = component_types.map{|t| type(t) }
|
235
|
+
name = name(name)
|
236
|
+
meta = metadata(metadata)
|
157
237
|
|
158
|
-
|
238
|
+
StructType.new(component_types, name, meta)
|
159
239
|
end
|
160
240
|
|
161
241
|
### Tuples and relations
|
162
242
|
|
163
|
-
def tuple(heading, name = nil)
|
243
|
+
def tuple(heading, name = nil, metadata = nil)
|
164
244
|
heading = heading(heading)
|
165
245
|
name = name(name)
|
246
|
+
meta = metadata(metadata)
|
166
247
|
|
167
|
-
TupleType.new(heading, name)
|
248
|
+
TupleType.new(heading, name, meta)
|
168
249
|
end
|
169
250
|
|
170
|
-
def
|
251
|
+
def multi_tuple(heading, name = nil, metadata = nil)
|
171
252
|
heading = heading(heading)
|
172
253
|
name = name(name)
|
254
|
+
meta = metadata(metadata)
|
173
255
|
|
174
|
-
|
256
|
+
MultiTupleType.new(heading, name, meta)
|
257
|
+
end
|
258
|
+
|
259
|
+
def relation(heading, name = nil, metadata = nil)
|
260
|
+
heading = heading(heading)
|
261
|
+
name = name(name)
|
262
|
+
meta = metadata(metadata)
|
263
|
+
|
264
|
+
RelationType.new(heading, name, meta)
|
265
|
+
end
|
266
|
+
|
267
|
+
def multi_relation(heading, name = nil, metadata = nil)
|
268
|
+
heading = heading(heading)
|
269
|
+
name = name(name)
|
270
|
+
meta = metadata(metadata)
|
271
|
+
|
272
|
+
MultiRelationType.new(heading, name, meta)
|
273
|
+
end
|
274
|
+
|
275
|
+
def proxy(target_name)
|
276
|
+
ProxyType.new(target_name)
|
175
277
|
end
|
176
278
|
|
177
279
|
private
|
178
280
|
|
281
|
+
def alias_type(type, name, metadata)
|
282
|
+
raise "Type expected `#{type}`" unless type.is_a?(Type)
|
283
|
+
if (name && type.named?) or (metadata && type.metadata?)
|
284
|
+
AliasType.new(type, name, metadata)
|
285
|
+
else
|
286
|
+
type.name = name if name
|
287
|
+
type.metadata = metadata if metadata
|
288
|
+
type
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
179
292
|
def fail!(message)
|
180
293
|
raise ArgumentError, message, caller
|
181
294
|
end
|