eac_config 0.1.0

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: 84f6dfb659545033cf9bd7ad9514ef8328ec32c13af6d3534c8cb884e716a3ee
4
+ data.tar.gz: a8fa8b10e98000122b2a9e479443d0975d55decf95a060474eaad7ecfa8f4dee
5
+ SHA512:
6
+ metadata.gz: 2d4c70a6acb8e033017a646ae5c1c1c3afe1b470fabcb194c8c8177fba8229d17abf13a504e58adf49983161a457a0d11b83ae1bc49a4917f80412672a9f518f
7
+ data.tar.gz: 383d7fb5e5812d1491dc73104c679b78b25c16b3e353591c3c37b2f467a3e1bd5f84de346bdb79c044a829dea0f7e32c898508dc1bd12bec42e290079efa74ca
data/lib/eac_config.rb ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EacConfig
6
+ require_sub __FILE__
7
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_config/entry_path'
4
+ require 'eac_ruby_utils/core_ext'
5
+
6
+ module EacConfig
7
+ class Entry
8
+ common_constructor :source_node, :path, :found, :value
9
+
10
+ def found?
11
+ found
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EacConfig
6
+ class EntryPath
7
+ PART_SEPARATOR = '.'
8
+
9
+ class << self
10
+ def build_parts(source)
11
+ return validate_parts!(source.split(PART_SEPARATOR)) if source.is_a?(::String)
12
+ return validate_parts!(source.flat_map { |part| build_parts(part) }) if
13
+ source.is_a?(::Enumerable)
14
+
15
+ build_parts(source.to_s)
16
+ end
17
+
18
+ def validate_parts!(parts)
19
+ parts.assert_argument(::Enumerable, 'parts')
20
+ parts.each_with_index do |part, index|
21
+ raise ::ArgumentError, "Part #{index} of #{parts} is blank" if part.blank?
22
+ raise ::ArgumentError, "Part #{index} is not a string" unless part.is_a?(::String)
23
+ end
24
+ end
25
+ end
26
+
27
+ attr_reader :parts
28
+
29
+ def initialize(*parts)
30
+ @parts = self.class.build_parts(parts).freeze
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_config/entry'
4
+ require 'eac_config/paths_hash'
5
+
6
+ module EacConfig
7
+ class EntrySearch
8
+ enable_simple_cache
9
+ common_constructor :node, :path
10
+
11
+ private
12
+
13
+ # @return [EacConfig::Entry]
14
+ def result_uncached
15
+ if paths_hash.key?(to_paths_hash_key)
16
+ ::EacConfig::Entry.new(node, path, true, paths_hash.fetch(to_paths_hash_key))
17
+ else
18
+ ::EacConfig::Entry.new(nil, path, false, nil)
19
+ end
20
+ end
21
+
22
+ # @return [EacConfig::PathsHash]
23
+ def paths_hash_uncached
24
+ ::EacConfig::PathsHash.new(node.data)
25
+ end
26
+
27
+ def to_paths_hash_key
28
+ path.parts.join('.')
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EacConfig
6
+ class Manager
7
+ common_constructor :root_node
8
+
9
+ # @return [EacConfig::Entry]
10
+ def entry(*parts)
11
+ root_node.entry(*parts)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EacConfig
6
+ class PathsHash
7
+ require_sub __FILE__
8
+
9
+ class << self
10
+ def parse_entry_key(entry_key)
11
+ r = entry_key.to_s.strip
12
+ raise ::EacConfig::PathsHash::EntryKeyError, 'Entry key cannot start or end with dot' if
13
+ r.start_with?('.') || r.end_with?('.')
14
+
15
+ r = r.split('.').map(&:strip)
16
+ if r.empty?
17
+ raise ::EacConfig::PathsHash::EntryKeyError, "Entry key \"#{entry_key}\" is empty"
18
+ end
19
+ return r.map(&:to_sym) unless r.any?(&:blank?)
20
+
21
+ raise ::EacConfig::PathsHash::EntryKeyError,
22
+ "Entry key \"#{entry_key}\" has at least one blank part"
23
+ end
24
+ end
25
+
26
+ attr_reader :root
27
+
28
+ def initialize(source_hash = {})
29
+ @root = Node.new(source_hash)
30
+ end
31
+
32
+ def [](entry_key)
33
+ root.read_entry(::EacConfig::PathsHash::PathSearch.parse_entry_key(entry_key))
34
+ end
35
+
36
+ def []=(entry_key, entry_value)
37
+ root.write_entry(
38
+ ::EacConfig::PathsHash::PathSearch.parse_entry_key(entry_key), entry_value
39
+ )
40
+ end
41
+
42
+ def fetch(entry_key)
43
+ root.fetch(::EacConfig::PathsHash::PathSearch.parse_entry_key(entry_key))
44
+ end
45
+
46
+ def key?(entry_key)
47
+ root.entry?(::EacConfig::PathsHash::PathSearch.parse_entry_key(entry_key))
48
+ end
49
+
50
+ delegate :to_h, to: :root
51
+
52
+ private
53
+
54
+ attr_reader :data
55
+ end
56
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacConfig
4
+ class PathsHash
5
+ class EntryKeyError < StandardError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'eac_config/paths_hash/entry_key_error'
5
+
6
+ module EacConfig
7
+ class PathsHash
8
+ class Node
9
+ PATH_SEARCH_UNENDED_ERROR_MESSAGE = 'Path search is not a Node and is not ended'
10
+
11
+ def initialize(source_hash)
12
+ source_hash.assert_argument(Hash, 'source_hash')
13
+ @data = source_hash.map { |k, v| [k.to_sym, v.is_a?(Hash) ? Node.new(v) : v] }.to_h
14
+ end
15
+
16
+ def entry?(path_search)
17
+ return false unless data.key?(path_search.cursor)
18
+ return true if path_search.ended?
19
+ return data.fetch(path_search.cursor).entry?(path_search.succeeding) if
20
+ data.fetch(path_search.cursor).is_a?(Node)
21
+
22
+ false # Paths continue and there is not available nodes
23
+ end
24
+
25
+ def fetch(path_search)
26
+ if data.key?(path_search.cursor)
27
+ node = data.fetch(path_search.cursor)
28
+ return (node.is_a?(Node) ? node.to_h : node) if path_search.ended?
29
+ return nil if node.blank?
30
+ return node.fetch(path_search.succeeding) if node.is_a?(Node)
31
+ end
32
+
33
+ path_search.raise_error(PATH_SEARCH_UNENDED_ERROR_MESSAGE)
34
+ end
35
+
36
+ def to_h
37
+ data.map { |k, v| [k, v.is_a?(Node) ? v.to_h : v] }.to_h
38
+ end
39
+
40
+ def read_entry(path_search)
41
+ node = data[path_search.cursor]
42
+ return (node.is_a?(Node) ? node.to_h : node) if path_search.ended?
43
+ return nil if node.blank?
44
+ return node.read_entry(path_search.succeeding) if node.is_a?(Node)
45
+
46
+ path_search.raise_error(PATH_SEARCH_UNENDED_ERROR_MESSAGE)
47
+ end
48
+
49
+ def write_entry(path_search, value)
50
+ if path_search.ended?
51
+ data[path_search.cursor] = value.is_a?(Hash) ? self.class.new(value) : value
52
+ else
53
+ assert_data_node(path_search.cursor).write_entry(path_search.succeeding, value)
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ attr_reader :data
60
+
61
+ def assert_data_node(key)
62
+ data[key] = self.class.new({}) unless data[key].is_a?(Node)
63
+ data[key]
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacConfig
4
+ class PathsHash
5
+ class PathSearch
6
+ class << self
7
+ def parse_entry_key(string)
8
+ new(::EacConfig::PathsHash.parse_entry_key(string), [])
9
+ end
10
+ end
11
+
12
+ common_constructor :current, :previous do
13
+ self.current = current.assert_argument(Array, 'current').freeze
14
+ self.previous = previous.assert_argument(Array, 'previous')
15
+ raise ::EacConfig::PathsHash::EntryKeyError, 'Current is empty' if current.empty?
16
+ end
17
+
18
+ def cursor
19
+ current.first
20
+ end
21
+
22
+ def ended?
23
+ current.count <= 1
24
+ end
25
+
26
+ def raise_error(message)
27
+ raise ::EacConfig::PathsHash::EntryKeyError, "#{message} (#{self})"
28
+ end
29
+
30
+ def succeeding
31
+ self.class.new(current[1..-1], previous + [cursor])
32
+ end
33
+
34
+ def to_s
35
+ "#{self.class}[Current: #{current}, Previous: #{previous}]"
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacConfig
4
+ module ReadableNode
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacConfig
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacConfig
4
+ module WriteableNode
5
+ end
6
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_config/entry'
4
+ require 'eac_config/entry_search'
5
+ require 'eac_config/readable_node'
6
+ require 'eac_config/writeable_node'
7
+ require 'eac_ruby_utils/core_ext'
8
+ require 'eac_ruby_utils/yaml'
9
+
10
+ module EacConfig
11
+ class YamlFileNode
12
+ include ::EacConfig::ReadableNode
13
+ include ::EacConfig::WriteableNode
14
+
15
+ common_constructor :path do
16
+ self.path = path.to_pathname
17
+ end
18
+
19
+ def data
20
+ @data ||= ::EacRubyUtils::Yaml.load_file(path)
21
+ end
22
+
23
+ def entry(*path)
24
+ ::EacConfig::EntrySearch.new(self, ::EacConfig::EntryPath.new(*path)).result
25
+ end
26
+ end
27
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: eac_config
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Put here the authors
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-05-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: eac_ruby_utils
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.62'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.62'
27
+ - !ruby/object:Gem::Dependency
28
+ name: eac_ruby_gem_support
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.2'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.2'
41
+ description:
42
+ email:
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - lib/eac_config.rb
48
+ - lib/eac_config/entry.rb
49
+ - lib/eac_config/entry_path.rb
50
+ - lib/eac_config/entry_search.rb
51
+ - lib/eac_config/manager.rb
52
+ - lib/eac_config/paths_hash.rb
53
+ - lib/eac_config/paths_hash/entry_key_error.rb
54
+ - lib/eac_config/paths_hash/node.rb
55
+ - lib/eac_config/paths_hash/path_search.rb
56
+ - lib/eac_config/readable_node.rb
57
+ - lib/eac_config/version.rb
58
+ - lib/eac_config/writeable_node.rb
59
+ - lib/eac_config/yaml_file_node.rb
60
+ homepage:
61
+ licenses: []
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubygems_version: 3.0.9
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: Put here de description.
82
+ test_files: []