yukata 1.0.0 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 035f88b6930ea44d8b6a545f46cc846b866e2a10
4
- data.tar.gz: 252211c052cf19518c3eccc446c2b7e6e8360fb3
3
+ metadata.gz: 68d1cd6c9e92b7ccbba49d39f24f4d20355a6c96
4
+ data.tar.gz: 8c9fab7697bc288497caecd0089dfde6e9310d57
5
5
  SHA512:
6
- metadata.gz: 077988b2e4d2b82763619357b229277ad1c06af0b882c7e7d2a0fbfb2b964cc74c36209932432275b5e4ad1c5c1a600da32ed617a5ebfacb88b389b4d7376499
7
- data.tar.gz: 999f22be5fd3aea13a36a4371928f78734a65598cd4186dbdb7ce8bbfe8e39a7ef9d6efe1821302fdc490377b4e104381b785f40c45f977d118d3be28c8373e4
6
+ metadata.gz: aaa51bd713c2164695f872340028cedcb1e9e5c2555a67c468a3e15e2294f73e79b171e71fdc41d9129f58e6f5fb086055a59bd786a83014995ba7bdf8f9f4a3
7
+ data.tar.gz: 34cd56683a72bad059963563054c9f20742e6398a55ac3113be0cb771732247421c68a1809d88ba8727f3b8e395df3edffa998408be328c062ff3b5a92680c7b
data/README.md CHANGED
@@ -2,6 +2,60 @@
2
2
 
3
3
  A light weight, no dependency, plain old ruby objects on steroids.
4
4
 
5
+ ## Example
6
+
7
+ ```ruby
8
+ require 'yukata'
9
+ require 'pp'
10
+
11
+ class Author < Yukata::Base
12
+ attribute :name, String
13
+ end
14
+
15
+ class Book < Yukata::Base
16
+ attribute :title, String
17
+ attribute :author, Author
18
+ attribute :created_at, Date, default: -> { Date.today }
19
+ end
20
+
21
+ book = Book.new({
22
+ title: 'Hunt For Red October',
23
+ author: {
24
+ name: 'Tom Clancy'
25
+ }
26
+ })
27
+
28
+ pp book
29
+ ```
30
+
31
+ ## Creating A Coercion
32
+
33
+ This library comes with a custom coercion library. It's fairly straight forward.
34
+
35
+ ```ruby
36
+ Yukata.coercer.register(String, URI) do |string, type|
37
+ #
38
+ # Maybe do some fancy string cleanup before you coerce it
39
+ #
40
+ URI(string)
41
+ end
42
+ ```
43
+
44
+ Then require that coercion to make sure it's loaded and all you simply have to
45
+ do now is just do the following.
46
+
47
+ ```ruby
48
+ require 'pp'
49
+
50
+ class Website < Yukata::Base
51
+ attribute :uri, URI
52
+ end
53
+
54
+ website = Website.new({uri: 'http://example.com'})
55
+
56
+ pp website
57
+ ```
58
+
5
59
  ## Contributing
6
60
 
7
61
  1. Fork it
@@ -1,6 +1,8 @@
1
1
  require 'json'
2
2
 
3
3
  require 'yukata/version'
4
+ require 'yukata/errors'
5
+ require 'yukata/coercion'
4
6
  require 'yukata/coercer'
5
7
 
6
8
  module Yukata
@@ -11,4 +13,13 @@ end
11
13
 
12
14
  require 'yukata/attribute'
13
15
  require 'yukata/base'
14
- require 'yukata/coercions'
16
+
17
+ require 'yukata/coercions/date'
18
+ require 'yukata/coercions/date_time'
19
+ require 'yukata/coercions/fixnum'
20
+ require 'yukata/coercions/float'
21
+ require 'yukata/coercions/integer'
22
+ require 'yukata/coercions/string'
23
+ require 'yukata/coercions/time'
24
+ require 'yukata/coercions/hash'
25
+ require 'yukata/coercions/boolean'
@@ -8,7 +8,8 @@ module Yukata
8
8
  # @param type [Class] the class this attribute represents
9
9
  # @param options [Hash] extra options that can be prescribed
10
10
  def initialize(type=String, options={})
11
- @type = type
11
+ @type = type
12
+
12
13
  if options[:default].is_a?(Proc)
13
14
  @default = options[:default]
14
15
  else
@@ -19,10 +20,5 @@ module Yukata
19
20
  def default
20
21
  @default.call
21
22
  end
22
-
23
- def coerce(obj)
24
- return obj if obj.is_a?(type)
25
- Yukata.coercer.coerce(obj, type)
26
- end
27
23
  end
28
24
  end
@@ -45,23 +45,20 @@ module Yukata
45
45
  self.attributes[name] = attr
46
46
  variable = "@#{name}"
47
47
 
48
- # SETTER
49
- setter = "#{name}="
50
- define_method(setter) do |arg|
51
- instance_variable_set(variable, attr.coerce(arg))
48
+ define_method("#{name}=") do |object|
49
+ val = Yukata.coercer.coerce(object, attr.type)
50
+ instance_variable_set(variable, val)
52
51
  end
53
52
 
54
- # GETTER
55
53
  define_method(name) do
56
54
  val = instance_variable_get(variable)
57
- unless val # Need to set the default
55
+ unless val
58
56
  val = attr.default
59
57
  instance_variable_set(variable, val)
60
58
  end
61
59
  val
62
60
  end
63
61
 
64
- Yukata.coercer.register(Hash, self) { |obj, type| type.new(obj) }
65
62
  end
66
63
  end
67
64
  end
@@ -1,8 +1,10 @@
1
1
  module Yukata
2
2
  class Coercer
3
3
  def initialize
4
- @coercions = Hash.new do |hash, key|
5
- hash[key] = Hash.new { -> (object) { object } }
4
+ @coercions = Hash.new do |hash, origin|
5
+ hash[origin] = Hash.new do |h, target|
6
+ h[target] = Coercion.new(origin, target)
7
+ end
6
8
  end
7
9
  @mutex = Mutex.new
8
10
  end
@@ -12,8 +14,10 @@ module Yukata
12
14
  # @param origin [Class] the class to convert
13
15
  # @param target [Class] what the origin will be converted to
14
16
  def register(origin, target, &block)
17
+ raise(ArgumentError, 'block is required') unless block_given?
18
+
15
19
  @mutex.synchronize do
16
- @coercions[origin][target] = block
20
+ @coercions[origin][target] = Coercion.new(origin, target, &block)
17
21
  end
18
22
  end
19
23
 
@@ -30,9 +34,7 @@ module Yukata
30
34
  # @param object [Object] the object to coerce
31
35
  # @param target [Class] what you want the object to turn in to
32
36
  def coerce(object, target)
33
- @mutex.synchronize do
34
- @coercions[object.class][target].call(object)
35
- end
37
+ @coercions[object.class][target].call(object)
36
38
  end
37
39
  end
38
40
  end
@@ -0,0 +1,17 @@
1
+ module Yukata
2
+ # @author Matthew A. Johnston
3
+ class Coercion
4
+ # Just passes the object on through
5
+ PASS_THROUGH = ->(obj, _) { obj }
6
+
7
+ def initialize(origin, target, &block)
8
+ @origin = origin
9
+ @target = target
10
+ @block = block_given? ? block : PASS_THROUGH
11
+ end
12
+
13
+ def call(object)
14
+ @block.call(object, @target)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1 @@
1
+ Yukata.coercer.coerce(Array, String) { |obj, _| obj.to_s }
@@ -0,0 +1,8 @@
1
+ unless defined?(Boolean)
2
+ class Boolean
3
+ end
4
+ end
5
+
6
+ Yukata.coercer.register(String, Boolean) do |string, _|
7
+ %w(1 on t true y yes).include?(string.downcase)
8
+ end
@@ -0,0 +1,2 @@
1
+ Yukata.coercer.register(Hash, String) { |obj, _| obj.to_s }
2
+ Yukata.coercer.register(Hash, Array) { |obj, _| obj.to_a }
@@ -1,5 +1,26 @@
1
- Yukata.coercer.register(String, Time) { |obj, type| type.parse(obj) }
2
- Yukata.coercer.register(String, Date) { |obj, type| type.parse(obj) }
3
- Yukata.coercer.register(String, DateTime) { |obj, type| type.parse(obj) }
1
+ Yukata.coercer.register(String, Time) do |obj, type|
2
+ begin
3
+ type.parse(obj)
4
+ rescue ArgumentError
5
+ nil
6
+ end
7
+ end
8
+
9
+ Yukata.coercer.register(String, Date) do |obj, type|
10
+ begin
11
+ type.parse(obj)
12
+ rescue ArgumentError
13
+ nil
14
+ end
15
+ end
16
+
17
+ Yukata.coercer.register(String, DateTime) do |obj, type|
18
+ begin
19
+ type.parse(obj)
20
+ rescue ArgumentError
21
+ nil
22
+ end
23
+ end
24
+
4
25
  Yukata.coercer.register(String, Integer) { |obj, _| obj.to_i }
5
- Yukata.coercer.register(String, Float) { |obj, _| obj.to_f }
26
+ Yukata.coercer.register(String, Float) { |obj, _| obj.to_f }
@@ -1,3 +1,3 @@
1
1
  module Yukata
2
- VERSION = '1.0.0'
2
+ VERSION = '1.1.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yukata
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Johnston
@@ -71,11 +71,14 @@ files:
71
71
  - lib/yukata/attribute.rb
72
72
  - lib/yukata/base.rb
73
73
  - lib/yukata/coercer.rb
74
- - lib/yukata/coercions.rb
74
+ - lib/yukata/coercion.rb
75
+ - lib/yukata/coercions/array.rb
76
+ - lib/yukata/coercions/boolean.rb
75
77
  - lib/yukata/coercions/date.rb
76
78
  - lib/yukata/coercions/date_time.rb
77
79
  - lib/yukata/coercions/fixnum.rb
78
80
  - lib/yukata/coercions/float.rb
81
+ - lib/yukata/coercions/hash.rb
79
82
  - lib/yukata/coercions/integer.rb
80
83
  - lib/yukata/coercions/string.rb
81
84
  - lib/yukata/coercions/time.rb
@@ -1,12 +0,0 @@
1
- module Yukata
2
- module Coercions
3
- end
4
- end
5
-
6
- require 'yukata/coercions/date'
7
- require 'yukata/coercions/date_time'
8
- require 'yukata/coercions/fixnum'
9
- require 'yukata/coercions/float'
10
- require 'yukata/coercions/integer'
11
- require 'yukata/coercions/string'
12
- require 'yukata/coercions/time'