typero 0.2.7 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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