lib/key_tree.rb in key_tree-0.2.0 vs lib/key_tree.rb in key_tree-0.3.0
- old
+ new
@@ -20,6 +20,64 @@
KeyTree::Forest[*contents]
else
raise ArgumentError, "can't load #{contents.class} into a KeyTree"
end
end
+
+ # Load a KeyTree from some external serialization
+ #
+ # load +type+: +serialization+
+ #
+ # +type+ is upcased to form a class name that should provide a
+ # +.load+ class method (like YAML or JSON does).
+ #
+ # Example:
+ # load(yaml: "---\na: 1\n")
+ # => {"a" => 1}
+ #
+ def self.load(typed_serialization = {})
+ unless typed_serialization.size == 1
+ raise ArgumentError, "pick one: #{typed_serialization.keys}"
+ end
+
+ type, serialization = typed_serialization.flatten
+
+ loader = get_loader(type)
+ self[loader.load(serialization)].with_meta_data do |meta_data|
+ meta_data << { load: { type: type.to_sym,
+ loader: loader } }
+ end
+ end
+
+ # Open an external file and load contents into a KeyTree
+ #
+ def self.open(file_name)
+ type = File.extname(file_name)[/[^.]+/]
+ keytree = File.open(file_name, mode: 'rb:utf-8') do |file|
+ load_from_file(file, type)
+ end
+
+ return keytree unless block_given?
+ yield(keytree)
+ end
+
+ private_class_method
+
+ # Get a class for loading external serialization for +type+
+ # +require+s the class provider if necessary.
+ #
+ def self.get_loader(type)
+ Class.const_get(type.upcase)
+ rescue NameError
+ require type.to_s
+ retry
+ end
+
+ def self.load_from_file(file, type)
+ load(type => file.read).with_meta_data do |meta_data|
+ file_path = file.path
+ meta_data << { file: { path: file_path,
+ name: File.basename(file_path),
+ dir: File.dirname(file_path) } }
+ end
+ end
end