File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -26,6 +26,10 @@ smooth transition to the new APIs.
2626 [ Tree::TreeNode#print_tree_to_s] [ print_tree_to_s ] returns the formatted
2727 output as a string.
2828
29+ * Hash conversion now accepts hash-like inputs (objects responding to
30+ ` to_hash ` ) to improve interoperability with frameworks such as Rails
31+ (see #104 ).
32+
2933## Release 2.2.0 Changes
3034
3135* [ Tree::TreeNode#add] [ add ] now raises ` ArgumentError ` when attempting to add
Original file line number Diff line number Diff line change 1919* Allow ` print_tree ` to write to a custom IO and add ` print_tree_to_s ` for
2020 string output.
2121
22+ * Accept hash-like inputs (` to_hash ` ) in hash conversion to support Rails
23+ ` HashWithIndifferentAccess ` data (see #104 ).
24+
2225### 2.2.1pre / 2026-02-07
2326
2427* Simplified development dependency constraints while maintaining Ruby 2.7+
Original file line number Diff line number Diff line change @@ -54,6 +54,12 @@ def self.included(base)
5454 # class methods on any class mixing in the {Tree::Utils::HashConverter}
5555 # module.
5656 module ClassMethods
57+ def normalize_hash_input ( value )
58+ return value . to_hash if value . respond_to? ( :to_hash )
59+
60+ value
61+ end
62+
5763 # Factory method builds a {Tree::TreeNode} from a +Hash+.
5864 #
5965 # This method will interpret each key of your +Hash+ as a {Tree::TreeNode}.
@@ -98,11 +104,13 @@ module ClassMethods
98104 # values that are not hashes or nils.
99105
100106 def from_hash ( hash )
107+ hash = normalize_hash_input ( hash )
101108 raise ArgumentError , 'Argument must be a type of hash' unless hash . is_a? ( Hash )
102109
103110 raise ArgumentError , 'Hash must have one top-level element' if hash . size != 1
104111
105112 root , children = hash . first
113+ children = normalize_hash_input ( children )
106114
107115 case children
108116 in Hash | nil
@@ -145,6 +153,7 @@ def from_hash(hash)
145153 # @return [Array] Array of child nodes added
146154 # @see ClassMethods#from_hash
147155 def add_from_hash ( children )
156+ children = self . class . normalize_hash_input ( children )
148157 raise ArgumentError , 'Argument must be a type of hash' unless children . is_a? ( Hash )
149158
150159 child_nodes = [ ]
Original file line number Diff line number Diff line change @@ -136,6 +136,25 @@ def test_from_hash_with_nils
136136 assert_equal ( 2 , interior_node . children . count )
137137 end
138138
139+ def test_from_hash_accepts_hash_like_inputs
140+ hash_like = Class . new do
141+ def initialize ( payload )
142+ @payload = payload
143+ end
144+
145+ def to_hash
146+ @payload
147+ end
148+ end
149+
150+ input = hash_like . new ( { A : hash_like . new ( { B : nil } ) } )
151+ tree = Tree ::TreeNode . from_hash ( input )
152+
153+ assert_equal ( :A , tree . name )
154+ assert_equal ( true , tree . root? )
155+ assert_equal ( true , tree [ :B ] . leaf? )
156+ end
157+
139158 def test_add_from_hash
140159 tree = Tree ::TreeNode . new ( :A )
141160
You can’t perform that action at this time.
0 commit comments