lib/bencodr/dictionary.rb in bencodr-1.2.0 vs lib/bencodr/dictionary.rb in bencodr-2.0.0
- old
+ new
@@ -1,57 +1,29 @@
# encoding: UTF-8
module BEncodr
module Dictionary
- module Generic
- module InstanceMethods
- # Encodes an array into a bencoded dictionary. Bencoded dictionaries are encoded as a 'd' followed by a list of
- # alternating keys and their corresponding values followed by an 'e'. Keys appear in sorted order (sorted as raw
- # strings, not alphanumerics).
- #
- # {:cow => "moo", :seven => 7}.bencodr #=> "d3:cow3:moo5:seveni7ee"
- #
- # @return [::String] the bencoded dictionary
- def bencode
- (respond_to?(:to_h) ? to_h : to_hash).bencode
- end
- end
+ def bencode
+ Dictionary.bencode(self)
end
-
- # Registers a class as an object that can be converted into a bencoded dictionary. Class must have instance method
- # to_h or to_hash.
- #
- # class MyClass
- # def to_h
- # {:a => :a, :b => 1}
- # end
- # end
- #
- # BEncodr::String.register MyClass
- # my_class = MyClass.new
- # my_class.bencodr #=> "d1:a1:a1:bi1ee"
- #
- # @param [Class#to_h, Class#to_hash] type the class to add the bencodr instance method to
- def self.register(type)
- type.send :include, Generic::InstanceMethods
+
+ def self.bencode(hashable)
+ hash = coerce(hashable)
+
+ hash.keys.sort{|a, b| a.to_s <=> b.to_s}.collect do |key|
+ BEncodr::String.bencode(key.to_s) + Object.bencode(hash[key])
+ end.unshift(:d).push(:e).join
end
-
- module Hash
- module InstanceMethods
- # Encodes an array into a bencoded dictionary. Bencoded dictionaries are encoded as a 'd' followed by a list of
- # alternating keys and their corresponding values followed by an 'e'. Keys appear in sorted order (sorted as raw
- # strings, not alphanumerics).
- #
- # {:cow => "moo", :seven => 7}.bencodr #=> "d3:cow3:moo5:seveni7ee"
- #
- # @return [::String] the bencoded dictionary
- def bencode
- keys.sort{|a, b| a.to_s <=> b.to_s}.collect do |key|
- key.to_s.bencode + self[key].bencode
- end.unshift(:d).push(:e).join
- end
+
+ private
+
+ def self.coerce(hashable)
+ if hashable.respond_to?(:to_h)
+ hashable.to_h
+ elsif hashable.respond_to?(:to_hash)
+ hashable.to_hash
+ else
+ raise BEncodeError, "BEncodr::Dictionary.bencode can only be called on an object that provides a to_h or to_hash method."
end
-
- ::Hash.send :include, InstanceMethods
end
end
end
\ No newline at end of file