typero 0.2.7 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.version +1 -0
- data/lib/typero.rb +111 -67
- data/lib/typero/type.rb +19 -96
- data/lib/typero/type/array.rb +22 -26
- data/lib/typero/type/boolean.rb +6 -8
- data/lib/typero/type/email.rb +11 -12
- data/lib/typero/type/float.rb +8 -14
- data/lib/typero/type/hash.rb +7 -5
- data/lib/typero/type/integer.rb +7 -13
- data/lib/typero/type/label.rb +6 -10
- data/lib/typero/type/string.rb +9 -7
- data/lib/typero/type/url.rb +7 -6
- data/lib/typero/type/utf_label.rb +11 -0
- metadata +9 -11
- data/lib/typero/hash.rb +0 -16
- data/lib/typero/instance.rb +0 -52
- data/lib/typero/schema.rb +0 -71
- data/lib/typero/version.rb +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '06869371b2f8a0fadb0c88f51a8a011aee2619a3'
|
4
|
+
data.tar.gz: 3593d80591d5a061fa02be6ef16816b3ee05c71d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e4720817d8fae4a96d5b65ac2d68d39aea79609a0e7be7f2828b137318ab0059a68661994d5551dbbc2fa9c5c21a8c33ec3902c8a99612007b15ceec8d7f662
|
7
|
+
data.tar.gz: 3551cfde3e9da75ddf74cc5c6deaa98476a37dba821644c8613d35fd2ecaede68270ff00f265731b2725a10f55c289bff7a99334a810b1c67dcee06a0202aa87
|
data/.version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.0
|
data/lib/typero.rb
CHANGED
@@ -1,91 +1,135 @@
|
|
1
|
-
|
1
|
+
# rules = Typero.new do
|
2
|
+
# set :name, String, req: true
|
3
|
+
# set :email, :email, req: true
|
4
|
+
# set :skills, [:email], min: 2
|
5
|
+
# end
|
6
|
+
#
|
7
|
+
# errors = rules.validate @object
|
8
|
+
# rules.valid?
|
9
|
+
# rules.validate(@object) { |errors| ... }
|
10
|
+
|
11
|
+
class Typero
|
12
|
+
attr_reader :rules
|
13
|
+
|
14
|
+
VERSION = File.read File.expand_path '../.version', File.dirname(__FILE__)
|
15
|
+
|
16
|
+
class << self
|
17
|
+
# validate single value in type
|
18
|
+
def validate value, type, opts={}
|
19
|
+
field = type.to_s.tableize.singularize.to_sym
|
20
|
+
|
21
|
+
# we need to have pointer to hash, so value can be changed (coerced) if needed
|
22
|
+
h = { field => value }
|
23
|
+
|
24
|
+
rule = new
|
25
|
+
rule.set field, type, opts
|
26
|
+
|
27
|
+
if error = rule.validate(h)[field]
|
28
|
+
block_given? ? yield(error) : raise(TypeError.new(error))
|
29
|
+
end
|
2
30
|
|
3
|
-
|
4
|
-
|
5
|
-
require_relative './typero/type'
|
6
|
-
require_relative './typero/hash'
|
31
|
+
h[field]
|
32
|
+
end
|
7
33
|
|
8
|
-
|
34
|
+
def cache
|
35
|
+
@@cache ||= {}
|
36
|
+
end
|
37
|
+
end
|
9
38
|
|
10
|
-
|
11
|
-
# attribute :name, req:'Link name is required'
|
12
|
-
# attribute :tags, Array[:label]
|
13
|
-
# attribute :bucket_id, Integer, req:'Bucket is not assigned'
|
14
|
-
# attribute :kind, String, allow:[:doc, :img, :vid, :lnk, :art], default:'lnk'
|
15
|
-
# attribute :email, :email, req:true, uniq:"Email is allready registred", protected:"You are not allowed to change the email"
|
39
|
+
###
|
16
40
|
|
17
|
-
#
|
41
|
+
# accepts dsl block to
|
42
|
+
def initialize hash={}, &block
|
43
|
+
@rules = {}
|
44
|
+
hash.each { |k, v| set(k, v) }
|
45
|
+
instance_exec &block if block
|
46
|
+
end
|
18
47
|
|
19
|
-
|
20
|
-
|
48
|
+
# coerce opts values
|
49
|
+
def parse_option opts
|
50
|
+
opts[:type] ||= 'string'
|
51
|
+
opts[:req] = opts.delete(:required) unless opts[:required].nil?
|
21
52
|
|
22
|
-
|
53
|
+
if opts[:type].is_a?(Array)
|
54
|
+
opts[:array_type] = opts[:type][0] if opts[:type][0]
|
55
|
+
opts[:type] = 'array'
|
56
|
+
end
|
23
57
|
|
24
|
-
|
25
|
-
@opts
|
26
|
-
end
|
58
|
+
opts[:type] = opts[:type].to_s.downcase
|
27
59
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
opts[:name] = name
|
60
|
+
allowed_names = [:req, :uniq, :protected, :type, :min, :max, :array_type, :default, :downcase, :desc]
|
61
|
+
opts.keys.each do |key|
|
62
|
+
raise ArgumentError.new('%s is not allowed as typero option' % key) unless allowed_names.index(key)
|
63
|
+
end
|
33
64
|
|
34
|
-
|
35
|
-
|
36
|
-
@opts[klass.to_s][name] = type_klass.new(opts).freeze
|
65
|
+
opts
|
66
|
+
end
|
37
67
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
68
|
+
# used in dsl to define value
|
69
|
+
def set field, type=String, opts={}
|
70
|
+
opts = type.is_a?(Hash) ? type : opts.merge(type: type)
|
42
71
|
|
43
|
-
|
44
|
-
Typero.opts['#{klass}'][:#{name}].set_value(self, value)
|
45
|
-
end
|
46
|
-
]
|
72
|
+
@rules[field] = parse_option opts
|
47
73
|
end
|
48
74
|
|
49
|
-
def
|
50
|
-
|
75
|
+
def safe_type type
|
76
|
+
type.to_s.gsub(/[^\w]/,'').classify
|
51
77
|
end
|
52
78
|
|
53
|
-
#
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
if block
|
61
|
-
block.call($!.message)
|
62
|
-
return false
|
79
|
+
# adds error to array or prefixes with field name
|
80
|
+
def add_error field, msg
|
81
|
+
if @errors[field]
|
82
|
+
@errors[field] += ', %s' % msg
|
83
|
+
else
|
84
|
+
field_name = field.to_s.sub(/_id$/,'').humanize
|
85
|
+
@errors[field] = '%s %s' % [field_name, msg]
|
63
86
|
end
|
64
|
-
raise(TypeError, $!.message)
|
65
87
|
end
|
66
88
|
|
67
|
-
#
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
89
|
+
# validates any instance object or object with hash variable interface
|
90
|
+
# it also coarces values
|
91
|
+
def validate instance
|
92
|
+
@errors = {}
|
93
|
+
|
94
|
+
@rules.each do |field, opts|
|
95
|
+
# set value to default if value is blank and default given
|
96
|
+
instance[field] = opts[:default] if opts[:default] && instance[field].blank?
|
97
|
+
|
98
|
+
# get field value
|
99
|
+
value = instance[field]
|
100
|
+
|
101
|
+
if value.present?
|
102
|
+
klass = 'Typero::%sType' % safe_type(opts[:type])
|
103
|
+
check = klass.constantize.new value, opts
|
104
|
+
check.value = check.default if check.value.nil?
|
105
|
+
|
106
|
+
unless check.value.nil?
|
107
|
+
begin
|
108
|
+
check.set
|
109
|
+
check.validate
|
110
|
+
instance[field] = check.value
|
111
|
+
rescue TypeError => e
|
112
|
+
add_error field, e.message
|
113
|
+
end
|
114
|
+
end
|
115
|
+
elsif opts[:req]
|
116
|
+
add_error field, 'is required' if opts[:req].class == TrueClass
|
117
|
+
end
|
118
|
+
end
|
74
119
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
120
|
+
if @errors.keys.length > 0 && block_given?
|
121
|
+
@errors.each { |k,v| yield(k, v) }
|
122
|
+
end
|
123
|
+
|
124
|
+
@errors
|
80
125
|
end
|
81
126
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
for key in (hash || {}).keys
|
86
|
-
raise TypeError, "Key :#{key} is not allowed in hash" unless args.index(key)
|
87
|
-
end
|
88
|
-
hash
|
127
|
+
def valid? instance
|
128
|
+
errors = validate instance
|
129
|
+
errors.keys.length == 0
|
89
130
|
end
|
90
131
|
end
|
91
132
|
|
133
|
+
require_relative 'typero/type'
|
134
|
+
|
135
|
+
Dir['%s/typero/type/*.rb' % File.dirname(__FILE__)].each { |file| require file }
|
data/lib/typero/type.rb
CHANGED
@@ -1,104 +1,27 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
class Typero::Type
|
2
|
+
attr_accessor :opts
|
3
|
+
attr_accessor :value
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
attr_accessor :opts
|
10
|
-
|
11
|
-
### SAFE TO OVERLOAD: START
|
12
|
-
|
13
|
-
# if value is not blank, it is sent to set method
|
14
|
-
def set(value)
|
15
|
-
value
|
16
|
-
end
|
17
|
-
|
18
|
-
# sometimes we want to coarce values on get
|
19
|
-
# by default just copy
|
20
|
-
def get(list)
|
21
|
-
list
|
22
|
-
end
|
23
|
-
|
24
|
-
# if value is blank?, trigger default
|
25
|
-
# for example set it to false for boolean type and [] for array type
|
26
|
-
def default
|
27
|
-
nil
|
28
|
-
end
|
29
|
-
|
30
|
-
# default validation for any type
|
31
|
-
def validate(what)
|
32
|
-
true
|
33
|
-
end
|
34
|
-
|
35
|
-
### SAFE TO OVERLOAD: END
|
36
|
-
|
37
|
-
# set options
|
38
|
-
def initialize(opts={})
|
39
|
-
@type = self.class.to_s.split('::')[1].sub('Type','').downcase.to_sym
|
40
|
-
@opts = opts
|
41
|
-
@name = opts.delete(:name)
|
42
|
-
end
|
43
|
-
|
44
|
-
def check_type(type)
|
45
|
-
type_klass = "Typero::#{type.to_s.classify}Type"
|
46
|
-
(type_klass.constantize rescue false) ? true : false
|
47
|
-
end
|
48
|
-
|
49
|
-
def get_value(instance)
|
50
|
-
# get current var value
|
51
|
-
value = instance.respond_to?('[]') ? instance[@name] : instance.instance_variable_get("@#{@name}")
|
52
|
-
if value.nil?
|
53
|
-
if @opts[:default]
|
54
|
-
@opts[:default].class.to_s == 'Proc' ? @opts[:default].call(instance) : @opts[:default]
|
55
|
-
else
|
56
|
-
return default
|
57
|
-
end
|
58
|
-
else
|
59
|
-
get(value)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def set_value(instance, value=nil)
|
64
|
-
if !value.blank?
|
65
|
-
# for user emails, once defined cant be overitten
|
66
|
-
if @opts[:protected] && get_value(instance) && get_value(instance) != value
|
67
|
-
raise TypeError, @opts[:protected].class == TrueClass ? "#{@name.capitalize} is allready defined and can't be overwritten." : @opts[:protected]
|
68
|
-
end
|
5
|
+
def initialize(value, opts)
|
6
|
+
@value = value
|
7
|
+
@opts = opts
|
8
|
+
end
|
69
9
|
|
70
|
-
|
10
|
+
# default validation for any type
|
11
|
+
def validate(what)
|
12
|
+
true
|
13
|
+
end
|
71
14
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
not_unique = false
|
76
|
-
if instance.respond_to?(:is_unique_field?)
|
77
|
-
not_unique = !instance.is_unique_field?(@name, value)
|
78
|
-
else
|
79
|
-
filter = instance.class.select(:id).where("#{@name}=?", value)
|
80
|
-
filter = filter.where('id<>?', instance.id) if instance.id
|
81
|
-
not_unique = true if filter.first
|
82
|
-
end
|
83
|
-
raise TypeError, @opts[:uniq].class == TrueClass ? %[Field #{@name} is uniqe and value "#{value}" allready exists] : @opts[:uniq] if not_unique
|
84
|
-
end
|
15
|
+
def get
|
16
|
+
@value
|
17
|
+
end
|
85
18
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
raise TypeError, msg
|
90
|
-
else
|
91
|
-
value = default
|
92
|
-
end
|
19
|
+
def set
|
20
|
+
@value
|
21
|
+
end
|
93
22
|
|
94
|
-
|
95
|
-
|
96
|
-
instance[@name] = value
|
97
|
-
else
|
98
|
-
# fallback to instance variable if no hash (plain class, not AR or Sequel)
|
99
|
-
instance.instance_variable_set("@#{@name}", value)
|
100
|
-
end
|
101
|
-
end
|
23
|
+
def default
|
24
|
+
nil
|
102
25
|
end
|
103
26
|
end
|
104
27
|
|
data/lib/typero/type/array.rb
CHANGED
@@ -1,36 +1,32 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
end
|
1
|
+
class Typero::ArrayType < Typero::Type
|
2
|
+
def default
|
3
|
+
[]
|
4
|
+
end
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
11
|
-
value
|
6
|
+
def set
|
7
|
+
unless @value.class.to_s.index('Array')
|
8
|
+
@value = @value.to_s.sub(/^\{/,'').sub(/\}$/,'').split(/\s*,\s*/)
|
12
9
|
end
|
13
10
|
|
14
|
-
|
15
|
-
|
16
|
-
# value = value.to_a unless value.is_array?
|
11
|
+
@value.uniq!
|
12
|
+
@value.compact!
|
17
13
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
Typero.quick_set(el, type)
|
14
|
+
if type = @opts[:array_type]
|
15
|
+
@value.map! { |el|
|
16
|
+
Typero.validate(el, type) { |msg|
|
17
|
+
raise TypeError.new "'%s' %s (value in list)" % [el, msg]
|
23
18
|
}
|
24
|
-
|
25
|
-
|
26
|
-
value
|
19
|
+
}
|
27
20
|
end
|
28
21
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
22
|
+
# this converts Sequel::Postgres::PGArray to Array and fixes many problems
|
23
|
+
@value = @value.to_a if @value.class != Array
|
24
|
+
end
|
25
|
+
|
26
|
+
def validate
|
27
|
+
raise TypeError, 'Min array lenght is %s elements' % @opts[:min] if @opts[:min] && @value.length < @opts[:min]
|
28
|
+
raise TypeError, 'Max array lenght is %s elements' % @opts[:max] if @opts[:max] && @value.length > @opts[:max]
|
29
|
+
true
|
34
30
|
end
|
35
31
|
end
|
36
32
|
|
data/lib/typero/type/boolean.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
end
|
1
|
+
class Typero::BooleanType < Typero::Type
|
2
|
+
def default
|
3
|
+
false
|
4
|
+
end
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
end
|
6
|
+
def set
|
7
|
+
@value = [true, 1, '1', 'true', 'on'].include?(@value) ? true : false
|
10
8
|
end
|
11
9
|
end
|
12
10
|
|
data/lib/typero/type/email.rb
CHANGED
@@ -1,15 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
true
|
12
|
-
end
|
1
|
+
class Typero::EmailType < Typero::Type
|
2
|
+
|
3
|
+
def set
|
4
|
+
@value = @value.downcase.gsub(/\s+/,'+')
|
5
|
+
end
|
6
|
+
|
7
|
+
def validate
|
8
|
+
raise TypeError, 'is not having at least 8 characters' unless @value.to_s.length > 7
|
9
|
+
raise TypeError, 'is missing @' unless @value.include?('@')
|
10
|
+
raise TypeError, 'is in wrong format' unless @value =~ /^[\+\w\-\.]+\@[\w\-\.]+$/i
|
13
11
|
end
|
12
|
+
|
14
13
|
end
|
15
14
|
|
data/lib/typero/type/float.rb
CHANGED
@@ -1,19 +1,13 @@
|
|
1
|
-
|
2
|
-
class FloatType < Typero::Type
|
3
|
-
def set(value)
|
4
|
-
value.to_f
|
5
|
-
end
|
1
|
+
class Typero::FloatType < Typero::Type
|
6
2
|
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
def set
|
4
|
+
@value = @value.to_f
|
5
|
+
end
|
10
6
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
raise TypeError, "max lenght is #{@opts[:max]}" if @opts[:max] && value > @opts[:max]
|
15
|
-
true
|
16
|
-
end
|
7
|
+
def validate
|
8
|
+
raise TypeError, "min lenght is #{@opts[:min]}" if @opts[:min] && value < @opts[:min]
|
9
|
+
raise TypeError, "max lenght is #{@opts[:max]}" if @opts[:max] && value > @opts[:max]
|
17
10
|
end
|
11
|
+
|
18
12
|
end
|
19
13
|
|
data/lib/typero/type/hash.rb
CHANGED
data/lib/typero/type/integer.rb
CHANGED
@@ -1,17 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
end
|
6
|
-
|
7
|
-
def validate(input)
|
8
|
-
value = set(input)
|
9
|
-
|
10
|
-
raise TypeError, "min lenght is #{@opts[:min]}, you have #{value}" if @opts[:min] && value < @opts[:min]
|
11
|
-
raise TypeError, "max lenght is #{@opts[:max]}, you have #{value}" if @opts[:max] && value > @opts[:max]
|
1
|
+
class Typero::IntegerType < Typero::Type
|
2
|
+
def set
|
3
|
+
@value = @value.to_i
|
4
|
+
end
|
12
5
|
|
13
|
-
|
14
|
-
|
6
|
+
def validate
|
7
|
+
raise TypeError, 'min is %s, got %s' % [@opts[:min], @value] if @opts[:min] && @value < @opts[:min]
|
8
|
+
raise TypeError, 'max is %s, got %s' % [@opts[:max], @value] if @opts[:max] && @value > @opts[:max]
|
15
9
|
end
|
16
10
|
end
|
17
11
|
|
data/lib/typero/type/label.rb
CHANGED
@@ -1,13 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
end
|
1
|
+
class Typero::LabelType < Typero::Type
|
2
|
+
def set
|
3
|
+
@value = @value.to_s.gsub(/\s+/,'-').gsub(/[^\w\-]/,'')[0,30].downcase
|
4
|
+
end
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
true
|
10
|
-
end
|
6
|
+
def validate
|
7
|
+
raise TypeError, "Label is having unallowed characters" unless @value =~ /^[\w\-]+$/
|
11
8
|
end
|
12
9
|
end
|
13
|
-
|
data/lib/typero/type/string.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
class Typero::StringType < Typero::Type
|
2
|
+
def set
|
3
|
+
@value = @value.to_s unless @value.is_a?(String)
|
4
|
+
@value = @value.downcase if @opts[:downcase]
|
5
|
+
end
|
6
|
+
|
7
|
+
def validate
|
8
|
+
raise TypeError, 'min lenght is %s, you have %s' % [@opts[:min], @value.length] if @opts[:min] && @value.length < @opts[:min]
|
9
|
+
raise TypeError, 'max lenght is %s, you have %s' % [@opts[:max], @value.length] if @opts[:max] && @value.length > @opts[:max]
|
8
10
|
end
|
9
11
|
end
|
10
12
|
|
data/lib/typero/type/url.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
class Typero::UrlType < Typero::Type
|
2
|
+
def set
|
3
|
+
@value = 'http://%s' % @value unless @value.include?('://')
|
4
|
+
end
|
5
|
+
|
6
|
+
def validate
|
7
|
+
raise TypeError, 'URL is not starting with http' unless @value =~ /^https?:\/\/./
|
7
8
|
end
|
8
9
|
end
|
9
10
|
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: typero
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dino Reic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fast_blank
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '1'
|
27
27
|
description: Simple and fast ruby type system. Enforce types as Array, Email, Boolean
|
28
28
|
for ruby class instances
|
29
29
|
email: reic.dino@gmail.com
|
@@ -31,10 +31,8 @@ executables: []
|
|
31
31
|
extensions: []
|
32
32
|
extra_rdoc_files: []
|
33
33
|
files:
|
34
|
+
- "./.version"
|
34
35
|
- "./lib/typero.rb"
|
35
|
-
- "./lib/typero/hash.rb"
|
36
|
-
- "./lib/typero/instance.rb"
|
37
|
-
- "./lib/typero/schema.rb"
|
38
36
|
- "./lib/typero/type.rb"
|
39
37
|
- "./lib/typero/type/array.rb"
|
40
38
|
- "./lib/typero/type/boolean.rb"
|
@@ -45,7 +43,7 @@ files:
|
|
45
43
|
- "./lib/typero/type/label.rb"
|
46
44
|
- "./lib/typero/type/string.rb"
|
47
45
|
- "./lib/typero/type/url.rb"
|
48
|
-
- "./lib/typero/
|
46
|
+
- "./lib/typero/type/utf_label.rb"
|
49
47
|
homepage: https://github.com/dux/typero
|
50
48
|
licenses:
|
51
49
|
- MIT
|
@@ -66,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
64
|
version: '0'
|
67
65
|
requirements: []
|
68
66
|
rubyforge_project:
|
69
|
-
rubygems_version: 2.6.
|
67
|
+
rubygems_version: 2.6.10
|
70
68
|
signing_key:
|
71
69
|
specification_version: 4
|
72
70
|
summary: Ruby type system
|
data/lib/typero/hash.rb
DELETED
data/lib/typero/instance.rb
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
module Typero
|
2
|
-
module Instance
|
3
|
-
def self.included(base)
|
4
|
-
def base.attribute(name, *args)
|
5
|
-
if !args[0]
|
6
|
-
opts = { type: :string }
|
7
|
-
elsif args[0].class.to_s == 'Hash'
|
8
|
-
if args[0].keys.length == 0
|
9
|
-
opts = { type: :hash }
|
10
|
-
else
|
11
|
-
type = args[0][:type] || :string
|
12
|
-
opts = args[0].merge( type: type )
|
13
|
-
end
|
14
|
-
elsif args[1]
|
15
|
-
opts = args[1]
|
16
|
-
opts[:type] = args[0]
|
17
|
-
else
|
18
|
-
opts = { type: args[0] }
|
19
|
-
end
|
20
|
-
|
21
|
-
if opts[:type].class.to_s == 'Array' && opts[:type][0] # Array[:email] -> array of emails
|
22
|
-
opts[:array_type] = opts[:type][0].to_s.downcase.to_sym
|
23
|
-
opts[:type] = :array
|
24
|
-
end
|
25
|
-
|
26
|
-
opts[:type] = opts[:type].to_s.downcase.to_sym
|
27
|
-
opts[:type] = :array if opts[:type] == :[]
|
28
|
-
opts[:req] = "#{name.to_s.humanize.capitalize} is required" if opts[:req].class == TrueClass
|
29
|
-
|
30
|
-
Typero.define_instance(self, name, opts)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
# def attributes=(opts)
|
35
|
-
# for k,v in opts
|
36
|
-
# send("#{k}=", v)
|
37
|
-
# end
|
38
|
-
# end
|
39
|
-
|
40
|
-
def attribute_errors
|
41
|
-
# hash = InstanceAttributes.opts[self.class.to_s]
|
42
|
-
klass = self.class.to_s
|
43
|
-
opts = Typero.opts[klass]
|
44
|
-
return [] unless opts
|
45
|
-
errors = []
|
46
|
-
for k, v in opts
|
47
|
-
errors.push [k, v.opts[:req]] if v.opts[:req] && self[k].blank?
|
48
|
-
end
|
49
|
-
errors
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
data/lib/typero/schema.rb
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
# validates hash against the schema
|
2
|
-
# good if you can create validate objects and check against for function parameters
|
3
|
-
# use whenever you want to check hash values of variables
|
4
|
-
# in Lux FW, used in api cell
|
5
|
-
|
6
|
-
# Typero::Schema.load_schema(email:{ req: true, type: :email}, age: { type: Integer, req: false })
|
7
|
-
module Typero
|
8
|
-
class Schema
|
9
|
-
class << self
|
10
|
-
# loads schema from hash and creates schema object
|
11
|
-
def load_schema(hash)
|
12
|
-
validate = new
|
13
|
-
for k,v in hash
|
14
|
-
validate.set(k,v)
|
15
|
-
end
|
16
|
-
validate
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
###
|
21
|
-
|
22
|
-
def initialize
|
23
|
-
@check = {}
|
24
|
-
end
|
25
|
-
|
26
|
-
# set field values to check
|
27
|
-
# :age, Integer, { min:18, max:110 }
|
28
|
-
# :email, :email, { req:false }
|
29
|
-
def set(field, opts={}, &block)
|
30
|
-
opts[:req] ||= true unless opts[:req].class == FalseClass
|
31
|
-
opts[:func] = block if block_given?
|
32
|
-
opts[:type] ||= String
|
33
|
-
@check[field] = opts
|
34
|
-
end
|
35
|
-
|
36
|
-
# check agains hash of values { email:'dux@net.hr', age:'40' }
|
37
|
-
def check(hash)
|
38
|
-
errors = {}
|
39
|
-
for field in @check.keys
|
40
|
-
value = hash[field]
|
41
|
-
check_hash = @check[field]
|
42
|
-
type = check_hash[:type]
|
43
|
-
|
44
|
-
if value.blank? && check_hash[:req].class != FalseClass
|
45
|
-
errors[field] = check_hash[:req].kind_of?(String) ? check_hash[:req] : "#{field.to_s.capitalize} is required"
|
46
|
-
next
|
47
|
-
end
|
48
|
-
|
49
|
-
if check_hash[:func]
|
50
|
-
begin
|
51
|
-
check_hash[:func].call(value.to_s)
|
52
|
-
rescue
|
53
|
-
errors[field] = $!.message
|
54
|
-
end
|
55
|
-
else
|
56
|
-
Typero.validate!(value, type, check_hash) { |msg|
|
57
|
-
errors[field] = "#{field.to_s.capitalize}: #{msg}"
|
58
|
-
}
|
59
|
-
|
60
|
-
# coerce value
|
61
|
-
hash[field] = Typero.quick_set(value, type) if value.present?
|
62
|
-
end
|
63
|
-
end
|
64
|
-
errors.keys.length > 0 ? errors : nil
|
65
|
-
end
|
66
|
-
|
67
|
-
def keys
|
68
|
-
@check.keys
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
data/lib/typero/version.rb
DELETED