tiny_dot 2.3.2 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tiny_dot.rb +62 -78
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8d79073c7292e31f88919b88dcf146c42118d81e94a2e94a3bfe7712b22124bd
4
- data.tar.gz: 59dff524acb74dc64ed050e2cc50ed4bd889199656782968326a5ec135ee0a9c
3
+ metadata.gz: f31f44aa3ecf2c601378a248041012313341a63f75db817baa6df5d82be0151e
4
+ data.tar.gz: 1787bff26e5ba21dfab2f696aa33bd4f17e0b35100073963db99e348e09081bc
5
5
  SHA512:
6
- metadata.gz: 1dfd42dfc4bc8bf15f94a5198c80124394b6a9302c70c731b9de69acad6fb57fc22706eda6a144932bb6c11bf200f21402d5886fa8c97f98a94da25bb285dcaf
7
- data.tar.gz: 7cd0fdf624c556b0993ca411a5824b5aae0f0fe453b20980b76d1a14410d125403e703eff9cec35abfbdf342bae9e90f2aea287c526c4a61227c9e08536ee019
6
+ metadata.gz: 9ec17f00dde5f6a9df6c7a8cb431b4bc3a349a5f84c8ffba1cbcea6b720ec1764cd635183132d6590e71e34ad49c84417b6c051bda6220bd44cb12dc7031c230
7
+ data.tar.gz: 25e0fc3511f15e829a886cfb9c29d7fce6d891c2af8d1032ba39fc5a062da8efbe8d6224d5091ad4923f700fae51ab64ff59974dcb89bdaca820e210b6a08c8c
data/lib/tiny_dot.rb CHANGED
@@ -1,95 +1,79 @@
1
- require 'yaml'
2
- require 'json'
1
+ require 'psych'
2
+ require 'oj'
3
3
 
4
- # this class gives you read-only access to Hases, JSON, and YAML files using
5
- # dot notation. it makes clever use of #method_missing to allow you to do the
6
- # following:
4
+ # The TinyDot module provides methods for converting data from different
5
+ # formats (environment variables, YAML, JSON and Hashes) into a nested Struct.
6
+ # This allows for easy access to the data using dot notation.
7
7
  #
8
- # > t = TinyDot.new({ 'foo' => { 'bar' => 'baz' }})
9
- # > t.foo # returns another instance of TinyDot
10
- # => #<TinyDot:0x0201243 @data={ 'bar' => 'baz' }>
11
- # > t.foo! # ! returns the value under the chain of keys
12
- # => { 'bar' => 'baz' }
8
+ # The `from_env` method converts the current environment variables into a
9
+ # Struct.
13
10
  #
14
- # ... in other words, it gives you a convenient dot notation syntax for
15
- # accessing nested hashes. you can chain calls to this and you'll get a new
16
- # object that's essentially a #dig into the top-level hash.
11
+ # The `from_yaml` method takes a string containing YAML data and converts it
12
+ # into a Struct.
17
13
  #
18
- # if you add '!' to the last method in a chain it will return the value under
19
- # that key.
14
+ # The `from_json` method takes a string containing JSON data and converts it
15
+ # into a Struct.
20
16
  #
21
- # finally, you can use dot syntax as deep as you want, and if there's no key at
22
- # that level you'll just get `nil' back:
17
+ # The `from_hash` method takes a Hash and converts it into a Struct. It really
18
+ # just calls the `_hash_to_struct` method.
23
19
  #
24
- # > t.foo.bar.baz.whatever.as.deep.as.you.want
25
- # => nil
20
+ # The `_hash_to_struct` is a private method that is used by the other methods
21
+ # to convert the data from a hash into a Struct. It handles nested data by
22
+ # recursively calling itself when it encounters a Hash or an array within the
23
+ # data.
26
24
  #
27
- # ... which is sort of safe navigation operator-like without the safe
28
- # navigation operator
29
- class TinyDot
30
- # returns a TinyDot instance from the ENV constant
31
- def self.from_env
32
- TinyDot.new(ENV)
33
- end
34
-
35
- # returns a TinyDot instance after parsing the YAML in the named filename
36
- def self.from_yaml_file(filename, permitted_classes: [])
37
- TinyDot.new(YAML.safe_load_file(filename, permitted_classes: permitted_classes))
38
- end
39
-
40
- # returns a TinyDot instance after parsing the JSON in the named filename
41
- def self.from_json_file(filename)
42
- TinyDot.new(JSON.parse(IO.read(filename)))
43
- end
25
+ # The `_to_attr_friendly_symbols` is a private method that is used to convert
26
+ # keys in the hash to symbols that can be used as attributes in a Struct. It
27
+ # replaces spaces and dashes with underscores and converts the keys to symbols.
28
+ #
29
+ # Please note that the JSON and YAML are required to be passed as String.
30
+ #
31
+ # Because this module constructs a series of nested Structs from Hash-like
32
+ # inputs, it means you can read/write data pretty easily:
33
+ #
34
+ # > s = TinyDot.from_json(<some deeply nested JSON>)
35
+ # => <struct ... >
36
+ # > s.foo.bar.baz
37
+ # => 5
38
+ # > s.foo.bar.baz = 99
39
+ # < s.foo.bar.baz
40
+ # => 99
41
+ module TinyDot
42
+ class << self
43
+ def from_env
44
+ _hash_to_struct(ENV.to_h)
45
+ end
44
46
 
45
- # returns a TinyDot instance after parsing the JSON in the string
46
- def self.from_json_string(s)
47
- TinyDot.new(JSON.parse(s))
48
- end
47
+ def from_yaml(yaml_string)
48
+ yaml = Psych.load(yaml_string)
49
+ _hash_to_struct(yaml)
50
+ end
49
51
 
50
- # give it a Hash and it'll give you dot notation over it
51
- def initialize(hash={})
52
- @data = hash
53
- end
52
+ def self.from_json(json_string)
53
+ json = Oj.load(json_string)
54
+ _hash_to_struct(json)
55
+ end
54
56
 
55
- def method_missing(m, *args)
56
- val = args.first
57
- ms = m.to_s
57
+ def self.from_hash(hash)
58
+ _hash_to_struct(json)
59
+ end
58
60
 
59
- case @data
60
- when Hash
61
- if ms.end_with?('!')
62
- @data[ms[0..-2]]
63
- elsif ms.end_with?('=')
64
- @data[m[0..-2]] = val
61
+ def _hash_to_struct(hash)
62
+ case hash
63
+ when Hash
64
+ struct = ::Struct.new(*_to_attr_friendly_symbols(hash.keys))
65
+ struct.new(*hash.values.map { |v| _hash_to_struct(v) })
66
+ when Array
67
+ hash.map { |v| _hash_to_struct(v) }
65
68
  else
66
- if @data.has_key?(ms)
67
- TinyDot.new(@data[ms])
68
- else
69
- TinyDot.new({})
70
- end
69
+ hash
71
70
  end
72
- else
73
- TinyDot.new({})
74
71
  end
75
- end
76
-
77
- def ==(other)
78
- @data == other.to_hash
79
- end
80
72
 
81
- def to_json
82
- @data.to_json
83
- end
84
-
85
- # NOTE: this returns the raw hash inside of the TinyDot instance, which means
86
- # if you modify anything here you're modifying the internal data in this
87
- # TinyDot instance
88
- def to_hash
89
- @data
90
- end
91
-
92
- def to_yaml
93
- @data.to_yaml
73
+ def _to_attr_friendly_symbols(keys)
74
+ keys
75
+ .map{|k| k.gsub(/[-\s]/, '_') }
76
+ .map(&:to_sym)
77
+ end
94
78
  end
95
79
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tiny_dot
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.2
4
+ version: 3.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Lunt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-26 00:00:00.000000000 Z
11
+ date: 2023-01-27 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: a tiny read/write dot notation wrapper for Hash, JSON, YAML, and ENV
14
14
  email: jefflunt@gmail.com