contours 0.1.1 → 0.2.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
  SHA256:
3
- metadata.gz: bef20ad206909adedfeef88608e80b3d069824bd647aa3fba108a8864e243e6a
4
- data.tar.gz: 65ae19ff7384c8e05bffcc7059b43827910c3c7ec270b94cd0edf5db7be0cc96
3
+ metadata.gz: e5586515f8a3343dd3facd5738d1bff58a0643b0e630e633d67c374ae077c00c
4
+ data.tar.gz: d168143703695cddf4fe429502a296dabf85702fd013bc42920bc8270ca365d0
5
5
  SHA512:
6
- metadata.gz: aec58c9140a958855efd069dbc90c58b80abf9f8c3c5d81814f8e3e5cd0f1c56f503f95078b0369469d2d41ced476767adea7a31e5e5a3af71e8563cb608fa6b
7
- data.tar.gz: 4ad14e697242a5d11d8df4ec0552c179f3d3231f2cebad1758b2b750dcb520f2d7ce0c5937f12c38b4b935dd9b3cdf8b237f4f01e763cdf832d1d481c07fc3c7
6
+ metadata.gz: e1652a33ebb6e2ec2efbc5b8aa494b60369a181b15970eea362ad264b7812a062830400154a0f8dfc6d78713079672022251ff9660a16f9b87e06953eb581679
7
+ data.tar.gz: 6088095e1dd8b5c89e9f3cbc456709a553c6260d6d4016e69eda213ec190392a42f35230eccceb4893c50b02d000e743a471eb1842714a161c61e42572f0a4f2
data/README.md CHANGED
@@ -44,7 +44,7 @@ You can specify a custom way to blend the values for the `@blended_keys`
44
44
  class Configuration < Contours::BlendedHash
45
45
  @blended_keys = %i[class data]
46
46
 
47
- blend(:class, with: StructuredString)
47
+ blend(:class, with: Contours::StructuredString)
48
48
 
49
49
  blend :data do |existing, new_value|
50
50
  existing.sum(new_value.sum)
@@ -60,7 +60,16 @@ config.to_h # => {class: "test overwrite", data: 21}
60
60
 
61
61
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
62
62
 
63
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
63
+ To install this gem onto your local machine, run `bundle exec rake install`.
64
+
65
+ This project is managed with [Reissue](https://github.com/SOFware/reissue).
66
+
67
+ To release a new version, make your changes and be sure to update the CHANGELOG.md.
68
+
69
+ To release a new version:
70
+
71
+ 1. `bundle exec rake build:checksum`
72
+ 2. `bundle exec rake release`
64
73
 
65
74
  ## Contributing
66
75
 
data/Rakefile CHANGED
@@ -11,3 +11,10 @@ Rake::TestTask.new(:test) do |t|
11
11
  end
12
12
 
13
13
  task default: :test
14
+
15
+ require "reissue/gem"
16
+
17
+ Reissue::Task.create do |t|
18
+ t.version_file = "lib/contours/version.rb"
19
+ t.version_limit = 3
20
+ end
@@ -27,8 +27,6 @@ module Contours
27
27
  #
28
28
  # See the source of this #{name} class for more details.
29
29
  class BlendedHash < DelegateClass(Hash)
30
- alias_method :to_hash, :__getobj__
31
-
32
30
  # Ensure that the initial hash is a BlendedHash
33
31
  def self.init(initial_hash)
34
32
  if initial_hash.is_a?(BlendedHash)
@@ -44,11 +42,34 @@ module Contours
44
42
  # Otherwise, the default implementation will be used where the value of the
45
43
  # with argument is expected to receive 'init' with the original value and
46
44
  # then 'merge' with the extras value.
45
+ #
46
+ # @param key [Symbol] the key that should be blended
47
+ # @param with [BlendedHash] the class that should be used to blend the value
48
+ # @param block [Proc] the implementation of the blend method
49
+ #
50
+ # @example
51
+ # class CssConfig < BlendedHash
52
+ # @blended_keys = %i[class]
53
+ # blend :class do |original, extras|
54
+ # [original, extras].flatten.compact.uniq.join(" ")
55
+ # end
56
+ # end
57
+ #
58
+ # CssConfig.new({class: "foo"}).merge({class: "bar"})
59
+ #
60
+ # @example
61
+ # class CssConfig < BlendedHash
62
+ # @blended_keys = %i[class]
63
+ # blend :class, with: CssConfig
64
+ # end
65
+ #
66
+ # CssConfig.new({class: "foo"}).merge({class: "bar"})
67
+ #
47
68
  def self.blend(key, with: nil, &block)
48
69
  if block
49
- define_method("blend_#{key}", &block)
70
+ define_method(:"blend_#{key}", &block)
50
71
  else
51
- define_method("blend_#{key}") do |original, extras|
72
+ define_method(:"blend_#{key}") do |original, extras|
52
73
  with.init(original).merge(extras)
53
74
  end
54
75
  end
@@ -57,12 +78,28 @@ module Contours
57
78
  # Recursively check for keys that are specified as blended and apply
58
79
  # the blend method to them or execute the blend_#{key} method if it exists
59
80
  # to set the new value.
81
+ #
82
+ # @param overrides [Hash] the hash to merge with
83
+ #
84
+ # @return [BlendedHash] the new hash
85
+ #
86
+ # @example
87
+ # class CssConfig < BlendedHash
88
+ # @blended_keys = %i[class]
89
+ # blend :class do |original, extras|
90
+ # [original, extras].flatten.compact.uniq.join(" ")
91
+ # end
92
+ # end
93
+ #
94
+ # config = CssConfig.new({class: "foo"}).merge({class: "bar"})
95
+ # config[:class] # => "foo bar"
96
+ #
60
97
  def merge(overrides)
61
98
  return self if overrides.nil? || overrides.empty?
62
99
  self.class.new(overrides.each_with_object(to_hash.dup) do |(key, value), hash|
63
100
  hash[key] = if blended_keys.include?(key)
64
- if respond_to?("blend_#{key}")
65
- send("blend_#{key}", hash[key], value)
101
+ if respond_to?(:"blend_#{key}")
102
+ send(:"blend_#{key}", hash[key], value)
66
103
  else
67
104
  blend(hash[key], value)
68
105
  end
@@ -75,26 +112,29 @@ module Contours
75
112
 
76
113
  # Ensure that the return value of these methods is a BlendedHash
77
114
  def [](...)
78
- if super.is_a?(Hash)
79
- self.class.init(super)
115
+ super_result = super
116
+ if super_result.is_a?(Hash)
117
+ self.class.init(super_result)
80
118
  else
81
- super
119
+ super_result
82
120
  end
83
121
  end
84
122
 
85
123
  def fetch(...)
86
- if super.is_a?(Hash)
87
- self.class.init(super)
124
+ super_result = super
125
+ if super_result.is_a?(Hash)
126
+ self.class.init(super_result)
88
127
  else
89
- super
128
+ super_result
90
129
  end
91
130
  end
92
131
 
93
132
  def dig(...)
94
- if super.is_a?(Hash)
95
- self.class.init(super)
133
+ super_result = super
134
+ if super_result.is_a?(Hash)
135
+ self.class.init(super_result)
96
136
  else
97
- super
137
+ super_result
98
138
  end
99
139
  end
100
140
 
@@ -110,7 +150,6 @@ module Contours
110
150
  # with a custom blend_#{key} method to customize the blending behavior for a
111
151
  # specific key.
112
152
  #
113
-
114
153
  def blend(original, extra)
115
154
  case original
116
155
  when BlendedHash, Hash
@@ -121,5 +160,24 @@ module Contours
121
160
  extra
122
161
  end
123
162
  end
163
+
164
+ def to_hash
165
+ deep_stringify_structured_strings(__getobj__)
166
+ end
167
+
168
+ private
169
+
170
+ def deep_stringify_structured_strings(obj)
171
+ case obj
172
+ when Hash
173
+ obj.transform_values { |v| deep_stringify_structured_strings(v) }
174
+ when Array
175
+ obj.map { |v| deep_stringify_structured_strings(v) }
176
+ when StructuredString
177
+ obj.to_s
178
+ else
179
+ obj
180
+ end
181
+ end
124
182
  end
125
183
  end
@@ -28,6 +28,16 @@ module Contours
28
28
 
29
29
  # Initialize with base string that is used to build the StructuredString
30
30
  # Other values will be added to the string in the order they are added.
31
+ #
32
+ # @param base [String] the initial string
33
+ # @param separator [String] the separator used to join the parts of the string
34
+ #
35
+ # @example
36
+ # config = StructuredString.new("input")
37
+ # config << "my-special-class"
38
+ # config << "input-error"
39
+ # config.to_s #=> "input my-special-class input-error"
40
+ #
31
41
  def initialize(base = "", separator: " ")
32
42
  @base = [base]
33
43
  @separator = separator
@@ -37,6 +47,14 @@ module Contours
37
47
  end
38
48
 
39
49
  # Add a value to the beginning of the string
50
+ #
51
+ # @param value [String] the value to add
52
+ #
53
+ # @example
54
+ # config = StructuredString.new("input")
55
+ # config.first("my-special-class")
56
+ # config.to_s #=> "my-special-class input"
57
+ #
40
58
  def first(value)
41
59
  @first << value.to_s
42
60
  __setobj__ to_s
@@ -44,6 +62,14 @@ module Contours
44
62
  end
45
63
 
46
64
  # Add a value to the end of the string
65
+ #
66
+ # @param value [String] the value to add
67
+ #
68
+ # @example
69
+ # config = StructuredString.new("input")
70
+ # config.last("input-error")
71
+ # config.to_s #=> "input input-error"
72
+ #
47
73
  def last(value)
48
74
  @last << value.to_s
49
75
  __setobj__ to_s
@@ -51,6 +77,14 @@ module Contours
51
77
  end
52
78
 
53
79
  # Add a value to the middle of the string
80
+ #
81
+ # @param value [String] the value to add
82
+ #
83
+ # @example
84
+ # config = StructuredString.new("input")
85
+ # config << "my-special-class"
86
+ # config.to_s #=> "input my-special-class"
87
+ #
54
88
  def <<(other)
55
89
  @other << other.to_s
56
90
  __setobj__ to_s
@@ -58,6 +92,21 @@ module Contours
58
92
  end
59
93
 
60
94
  # Read a particular portion of the structured string or raise an error
95
+ #
96
+ # @param key [Symbol] the portion of the string to read
97
+ #
98
+ # @return [Array] the portion of the string
99
+ #
100
+ # @example
101
+ # config = StructuredString.new("input")
102
+ # config << "my-special-class"
103
+ # config.first("first-class")
104
+ # config.last("last-class")
105
+ # config.read(:base) #=> ["input"]
106
+ # config.read(:first) #=> ["first-class"]
107
+ # config.read(:last) #=> ["last-class"]
108
+ # config.read(:other) #=> ["my-special-class"]
109
+ #
61
110
  def read(key)
62
111
  case key
63
112
  when :first
@@ -109,6 +158,17 @@ module Contours
109
158
  end
110
159
 
111
160
  # Return the string representation of the StructuredString
161
+ #
162
+ # @return [String] the string
163
+ #
164
+ # @example
165
+ # config = StructuredString.new("input")
166
+ # config << "my-special-class"
167
+ # config.last("last-class")
168
+ # config.first("first-class")
169
+ # config << "input-error"
170
+ # config.to_s #=> "first-class input my-special-class input-error last-class"
171
+ #
112
172
  def to_s
113
173
  [@first, @base, @other, @last]
114
174
  .flatten
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Contours
4
- VERSION = "0.1.1"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: contours
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Gay
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2023-11-04 00:00:00.000000000 Z
10
+ date: 2025-06-22 00:00:00.000000000 Z
12
11
  dependencies: []
13
12
  description: |
14
13
  Provides objects with which you can define a configuration object
@@ -33,7 +32,6 @@ metadata:
33
32
  homepage_uri: https://github.com/SOFware/contours
34
33
  source_code_uri: https://github.com/SOFware/contours.git
35
34
  changelog_uri: https://github.com/SOFware/contours/blob/main/CHANGELOG.md
36
- post_install_message:
37
35
  rdoc_options: []
38
36
  require_paths:
39
37
  - lib
@@ -48,8 +46,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
48
46
  - !ruby/object:Gem::Version
49
47
  version: '0'
50
48
  requirements: []
51
- rubygems_version: 3.4.20
52
- signing_key:
49
+ rubygems_version: 3.6.5
53
50
  specification_version: 4
54
51
  summary: Support for building customizable configuration objects.
55
52
  test_files: []