giri 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ce0c580bbf94b64b4aabe9b470cc631ea1ec0ce01bac6fe169b594022415a693
4
+ data.tar.gz: e78841c26884ad0d47df63e938fb04058123ee39b4aeeadc353cc2f4aa5a05a1
5
+ SHA512:
6
+ metadata.gz: 41e49781948e8d73d0c3b46a0a0bb645d5d23af55da76dcd4394b3b9202f6cc21ae044bbb6bbfa11be678027912acc347f3908f0d8a4df5ae4da36bfdaa0f1e8
7
+ data.tar.gz: 4d43d8b9db7be0184061ded67a1c2a417309af2da06baee4a2c436a729908c1117ee7a002e4858ab39ae97107ec4b7c9636c4e20b8dc808f227238fc96ceb35a
data/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # README
2
+
3
+ # DEVELOPMENT GUIDE
4
+
5
+ ## REPL
6
+
7
+ Since `Gemfile` has the line below, you just run `require "giri"` in `bundle exec irb` to start `Giri`.
8
+
9
+ ```
10
+ gem "giri", path: './'
11
+ ```
12
+
13
+ ```
14
+ bundle install
15
+ ```
16
+
17
+ ```
18
+ bundle exec irb
19
+
20
+ # (irb):> require "giri"
21
+ ```
22
+
23
+ ## Local Build
24
+
25
+ Since it has `Rakefile`, you just run the following command to make build and install it on your local.
26
+
27
+ ```
28
+ bundle exec rake build
29
+ bundle exec rake install
30
+ ```
31
+
32
+ Then you just run `require "giri"` in `irb` to start `Giri`.
33
+
34
+ ```
35
+ irb
36
+
37
+ (irb):> require "giri"
38
+ ```
39
+
40
+ ## Publish Gem
41
+
42
+ If you have the right to publish it to rubygems, run it.
43
+
44
+ ```
45
+ bundle exec rake build
46
+ gem push ./pkg/giri-${VERSION}.gem
47
+ ```
@@ -0,0 +1,7 @@
1
+ class Giri::BaseNode
2
+ extend Giri::Bud
3
+
4
+ def inspect
5
+ "#<#{self.class}:0x#{object_id.to_s(16)} @ref_name=#{@ref_name.inspect} parent_ref_name=#{parent_ref_name.inspect} @attributes=#{@attributes.inspect}>"
6
+ end
7
+ end
data/lib/giri/bud.rb ADDED
@@ -0,0 +1,185 @@
1
+ module Giri::Bud
2
+
3
+ def self.extended(base)
4
+ base.singleton_class.attr_accessor :xml_nodes, :xml_attributes, :with_name_default_for_node, :with_name_default_for_attribute
5
+
6
+ base.xml_nodes = {}
7
+ base.xml_attributes = []
8
+ # TODO: Set nil for default
9
+ base.with_name_default_for_node = :camelize
10
+ base.with_name_default_for_attribute = :lower_camelcase
11
+
12
+ base.class_eval do
13
+ attr_reader :node, :ref_name, :attributes, :parent
14
+ def initialize(*args)
15
+ initialize_setup(*args)
16
+ end
17
+
18
+ def initialize_setup(node, ref_name: nil, parent: nil)
19
+ @node = node
20
+ @ref_name = ref_name
21
+ @attributes = Hashie::Mash.new(build_attributes)
22
+ @parent = parent
23
+ end
24
+
25
+ def parent_ref_name
26
+ parent&.ref_name
27
+ end
28
+
29
+ def find_elements(name)
30
+ node.elements.select{|e| e.name == name}
31
+ end
32
+
33
+ def find_element(name)
34
+ node.elements.find{|e| e.name == name}
35
+ end
36
+
37
+ def where(&block)
38
+ block.call(node)
39
+ end
40
+
41
+ def build_attributes
42
+ self.class.xml_attributes.map do |col|
43
+ name = col[:name]
44
+ type = self.class.build_type(col[:type])
45
+ with_name = col[:with_name]
46
+
47
+ attr_name = self.class.build_attribute_name(name, with_name || self.class.with_name_default_for_attribute)
48
+ value = node.attributes[attr_name.to_s]&.value
49
+ value = if value
50
+ if type.is_a?(Class)
51
+ type.new(value)
52
+ elsif type.is_a?(Symbol)
53
+ "Giri::TextNode#{type.to_s.camelize}".constantize.build_value(value)
54
+ else
55
+ value
56
+ end
57
+ else
58
+ value
59
+ end
60
+ # value = (value && type) ? type.new(value) : value
61
+
62
+ [name.to_sym, value]
63
+ end.to_h
64
+ end
65
+ end
66
+ end
67
+
68
+ def inherited(base)
69
+ base.xml_nodes = xml_nodes.dup
70
+ base.xml_attributes = xml_attributes.dup
71
+ base.with_name_default_for_node = with_name_default_for_node
72
+ base.with_name_default_for_attribute = with_name_default_for_attribute
73
+ super
74
+ end
75
+
76
+ def spawn(&block)
77
+ Class.new(self, &block)
78
+ end
79
+
80
+ def text_node(name, **args, &block)
81
+ xml_node(name, type: "Giri::TextNodeString", **args, &block)
82
+ end
83
+
84
+ def integer_node(name, **args, &block)
85
+ xml_node(name, type: "Giri::TextNodeInteger", **args, &block)
86
+ end
87
+
88
+ def big_decimal_node(name, **args, &block)
89
+ xml_node(name, type: "Giri::TextNodeBigDecimal", **args, &block)
90
+ end
91
+
92
+ def date_time_node(name, **args, &block)
93
+ xml_node(name, type: "Giri::TextNodeDateTime", **args, &block)
94
+ end
95
+
96
+ def duration_node(name, **args, &block)
97
+ xml_node(name, type: "Giri::TextNodeDuration", **args, &block)
98
+ end
99
+
100
+ def xml_node_collection(name, **args, &block)
101
+ xml_node(name, collection: true, **args, &block)
102
+ end
103
+
104
+ def xml_node(name, type: nil, collection: nil, where: nil, with_name: nil, &block)
105
+ type = if block_given?
106
+ type = build_type(type || self.xml_nodes.dig(name.to_sym, :type) || "Giri::BaseNode")
107
+ type.spawn(&block)
108
+ else
109
+ build_type(type)
110
+ end
111
+
112
+ self.xml_nodes[name.to_sym] = {name: name, type: type, collection: collection}
113
+
114
+ class_eval do
115
+ define_method(name) do
116
+ var = instance_variable_get("@#{name}")
117
+ var || begin
118
+ attr_name = self.class.build_attribute_name(name, with_name || self.class.with_name_default_for_node)
119
+ elem = if where
120
+ where.call(node)
121
+ else
122
+ collection ?
123
+ find_elements(attr_name.to_s) :
124
+ find_element(attr_name.to_s)
125
+ end
126
+ elem = if collection
127
+ elem.empty? ? nil : elem
128
+ else
129
+ elem
130
+ end
131
+
132
+ if elem
133
+ # type = if block_given? # This block points the args in `xml_node` not method defined dynamically.
134
+ # type = self.class.build_type(type || "Giri::BaseNode")
135
+ # type.spawn(&block)
136
+ # else
137
+ # self.class.build_type(type)
138
+ # end
139
+ o = if collection
140
+ elem.map{|e| type ? type.new(e, ref_name: name, parent: self) : e}
141
+ else
142
+ type ? type.new(elem, ref_name: name, parent: self) : elem
143
+ end
144
+ instance_variable_set("@#{name}", o)
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
150
+
151
+ def xml_attribute(name, **args)
152
+ self.xml_attributes = self.xml_attributes.append(args.merge(name: name))
153
+
154
+ class_eval do
155
+ define_method(name) do
156
+ attributes.public_send(name)
157
+ end
158
+ end
159
+ end
160
+
161
+ def build_attribute_name(name, with_name)
162
+ if with_name.is_a?(String)
163
+ with_name
164
+ elsif [:underscore, :camelize, :camelcase].include?(with_name)
165
+ name.to_s.send(with_name).to_sym
166
+ elsif with_name == :lower_camelcase
167
+ name.to_s.camelize(:lower).to_sym
168
+ else
169
+ name
170
+ end
171
+ end
172
+
173
+ def build_type(type)
174
+ if type.is_a?(Class)
175
+ type
176
+ elsif type.is_a?(String)
177
+ # type.to_s.constantize
178
+ Object.const_get(type.to_s)
179
+ elsif type.is_a?(Symbol)
180
+ type
181
+ else
182
+ nil
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,15 @@
1
+ require "bigdecimal"
2
+ require "bigdecimal/util"
3
+
4
+ class Giri::TextNodeBigDecimal < DelegateClass(BigDecimal)
5
+ extend Giri::Bud
6
+
7
+ def self.build_value(str)
8
+ str.to_d
9
+ end
10
+
11
+ def initialize(*args)
12
+ initialize_setup(*args)
13
+ super(self.class.build_value(@node.text))
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ require "date"
2
+
3
+ class Giri::TextNodeDateTime < DelegateClass(DateTime)
4
+ extend Giri::Bud
5
+
6
+ def self.build_value(str)
7
+ DateTime.parse(str)
8
+ end
9
+
10
+ def initialize(*args)
11
+ initialize_setup(*args)
12
+ super(self.class.build_value(@node.text))
13
+ end
14
+ end
@@ -0,0 +1,24 @@
1
+ # https://www.w3.org/TR/xmlschema-2/#duration
2
+ class Giri::TextNodeDuration < Giri::TextNodeString
3
+
4
+ def components
5
+ @components ||= begin
6
+ _, years, months, days, time_part, hours, minutes, seconds = self.match(/\AP(\d+Y)?(\d+M)?(\d+D)?(T(\d+H)?(\d+M)?(\d+S)?)?\z/).to_a
7
+ # Example of values "15H" and "15H".to_i will get 15.
8
+ {
9
+ years: years.to_i,
10
+ months: months.to_i,
11
+ days: days.to_i,
12
+ hours: hours.to_i,
13
+ minutes: minutes.to_i,
14
+ seconds: seconds.to_i,
15
+ }
16
+ end
17
+ end
18
+
19
+ def duration_time
20
+ components.reduce(0) do |acc,(k,v)|
21
+ acc + v.public_send(k)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,12 @@
1
+ class Giri::TextNodeInteger < DelegateClass(Integer)
2
+ extend Giri::Bud
3
+
4
+ def self.build_value(str)
5
+ str.to_i
6
+ end
7
+
8
+ def initialize(*args)
9
+ initialize_setup(*args)
10
+ super(self.class.build_value(@node.text))
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ class Giri::TextNodeString < DelegateClass(String)
2
+ extend Giri::Bud
3
+
4
+ def initialize(*args)
5
+ initialize_setup(*args)
6
+ super(@node.text)
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ module Giri
2
+ VERSION = "0.0.3"
3
+ end
data/lib/giri.rb ADDED
@@ -0,0 +1,16 @@
1
+ require "hashie/mash"
2
+ require "active_support"
3
+ require "active_support/inflector"
4
+ require "active_support/core_ext/integer"
5
+
6
+ require "giri/version"
7
+ require "giri/bud"
8
+ require "giri/base_node"
9
+ require "giri/text_node_string"
10
+ require "giri/text_node_integer"
11
+ require "giri/text_node_big_decimal"
12
+ require "giri/text_node_date_time"
13
+ require "giri/text_node_duration"
14
+
15
+ module Giri
16
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: giri
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - metheglin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-08-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '13.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '13.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: hashie
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Giri
56
+ email: pigmybank@gmail.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - README.md
62
+ - lib/giri.rb
63
+ - lib/giri/base_node.rb
64
+ - lib/giri/bud.rb
65
+ - lib/giri/text_node_big_decimal.rb
66
+ - lib/giri/text_node_date_time.rb
67
+ - lib/giri/text_node_duration.rb
68
+ - lib/giri/text_node_integer.rb
69
+ - lib/giri/text_node_string.rb
70
+ - lib/giri/version.rb
71
+ homepage: https://rubygems.org/gems/giri
72
+ licenses:
73
+ - MIT
74
+ metadata: {}
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '2.7'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubygems_version: 3.1.4
91
+ signing_key:
92
+ specification_version: 4
93
+ summary: Giri
94
+ test_files: []