Module: Aduki

Defined in:
lib/aduki.rb,
lib/aduki/version.rb

Defined Under Namespace

Modules: ClassMethods, Initializer Classes: AttrFinder, Initializable, RecursiveHash

Constant Summary collapse

VERSION =
"0.2.3"

Class Method Summary collapse

Class Method Details

.apply_array_attribute(klass, object, getter, value) ⇒ Object



89
90
91
92
93
94
95
# File 'lib/aduki.rb', line 89

def self.apply_array_attribute klass, object, getter, value
  setter_method = "#{getter}=".to_sym
  return unless object.respond_to? setter_method
  array = object.send(getter) || []
  array << to_value(klass, getter, value)
  object.send(setter_method, array)
end

.apply_attribute(klass, object, setter, value) ⇒ Object



119
120
121
122
123
124
125
126
# File 'lib/aduki.rb', line 119

def self.apply_attribute klass, object, setter, value
  if setter.match(/\[\d+\]/)
    getter = setter.gsub(/\[\d+\]/, '').to_sym
    apply_array_attribute klass, object, getter, value
  else
    apply_single_attribute klass, object, setter, value
  end
end

.apply_attributes(object, attrs) ⇒ Object



128
129
130
131
132
133
134
135
# File 'lib/aduki.rb', line 128

def self.apply_attributes object, attrs
  setters = split_attributes(attrs || { })
  klass = object.class

  setters.sort.each do |setter, value|
    apply_attribute klass, object, setter, value
  end
end

.apply_new_single_attribute(klass, object, setter, value) ⇒ Object



97
98
99
100
101
102
# File 'lib/aduki.rb', line 97

def self.apply_new_single_attribute klass, object, setter, value
  setter_method = "#{setter}=".to_sym
  return unless object.respond_to? setter_method

  object.send setter_method, to_value(klass, setter, value)
end

.apply_single_attribute(klass, object, setter, value) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/aduki.rb', line 104

def self.apply_single_attribute klass, object, setter, value
  if value.is_a?(Hash)
    existing_value = object.send setter if object.respond_to?(setter)
    if existing_value
      if existing_value.is_a? Hash
        value.each { |k, v| existing_value[k] = v }
      else
        Aduki.apply_attributes existing_value, value
      end
      return
    end
  end
  apply_new_single_attribute klass, object, setter, value
end

.maybe_parse_date(str) ⇒ Object



34
35
36
37
# File 'lib/aduki.rb', line 34

def self.maybe_parse_date str
  return nil if (str == nil) || (str == '')
  Date.parse(str)
end

.split_attributes(attrs) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/aduki.rb', line 75

def self.split_attributes attrs
  setters = { }
  attrs.each do |setter, value|
    if setter.match(/\./)
      first, rest = setter.split(/\./, 2)
      setters[first] ||= { }
      setters[first][rest] = value
    else
      setters[setter] = value
    end
  end
  setters
end

.to_aduki(obj, collector = { }, key = "", join = "") ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/aduki.rb', line 8

def self.to_aduki obj, collector={ }, key="", join=""
  case obj
  when Hash
    obj.keys.inject(collector) { |result, k|
      v = obj[k]
      to_aduki v, collector, "#{key}#{join}#{k}", "."
      result
    }
  when Array
    obj.each_with_index do |av, ix|
      to_aduki av, collector, "#{key}[#{ix}]", "."
    end
  when String, Numeric, Symbol
    collector[key] = obj
  else
    vv = obj.instance_variables
    vv.each do |v|
      accessor = v.to_s.gsub(/^@/, "").to_sym
      if obj.respond_to?(accessor) && obj.respond_to?("#{accessor}=".to_sym)
        to_aduki obj.send(accessor), collector, "#{key}#{join}#{accessor}", "."
      end
    end
  end
  collector
end

.to_typed_hash(klass, value) ⇒ Object



66
67
68
69
70
71
72
73
# File 'lib/aduki.rb', line 66

def self.to_typed_hash klass, value
  setters = split_attributes value
  hsh = { }
  setters.each { |k, v|
    hsh[k] = klass.new(v)
  }
  hsh
end

.to_value(klass, setter, value) ⇒ Object



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/aduki.rb', line 39

def self.to_value klass, setter, value
  return value.map { |v| to_value klass, setter, v} if value.is_a? Array

  type = klass.aduki_type_for_attribute_name setter
  if type.is_a? Hash
    to_typed_hash type.values.first, value
  elsif type == Date
    case value
    when Date; value
    when String; maybe_parse_date(value)
    end
  elsif type == Time
    case value
    when Time; value
    when String; Time.parse(value)
    end
  elsif type && (type <= Integer)
    value.to_i
  elsif type && (type <= Float)
    value.to_f
  elsif type.respond_to? :aduki_find
    type.aduki_find value
  else
    type ? type.new(value) : value
  end
end