diff --git a/History.txt b/History.txt new file mode 100644 index 0000000..01c1e47 --- /dev/null +++ b/History.txt @@ -0,0 +1,2 @@ += + * Birthday! \ No newline at end of file diff --git a/README.rdoc b/README.md similarity index 55% rename from README.rdoc rename to README.md index 866f621..7422421 100644 --- a/README.rdoc +++ b/README.md @@ -1,9 +1,28 @@ -= bert +BERT +==== -Description goes here. +BERT is a BERT (Binary ERlang Term) serialization library for Ruby. It can +encode Ruby objects into BERT format and decode BERT binaries into Ruby +objects. + + +Installation +------------ + + gem install bert -s http://gemcutter.org + + +Usage +----- + + require 'bert' + + BERT.encode([ + + +Note on Patches/Pull Requests +----------------------------- -== Note on Patches/Pull Requests - * Fork the project. * Make your feature addition or bug fix. * Add tests for it. This is important so I don't break it in a @@ -13,6 +32,8 @@ Description goes here. bump version in a commit by itself I can ignore when I pull) * Send me a pull request. Bonus points for topic branches. -== Copyright + +Copyright +--------- Copyright (c) 2009 Tom Preston-Werner. See LICENSE for details. diff --git a/Rakefile b/Rakefile index 049089d..ff4689d 100644 --- a/Rakefile +++ b/Rakefile @@ -5,12 +5,13 @@ begin require 'jeweler' Jeweler::Tasks.new do |gem| gem.name = "bert" - gem.summary = %Q{TODO: one-line summary of your gem} - gem.description = %Q{TODO: longer description of your gem} + gem.summary = %Q{BERT Serializiation for Ruby} + gem.description = %Q{BERT Serializiation for Ruby} gem.email = "tom@mojombo.com" gem.homepage = "http://github.com/mojombo/bert" gem.authors = ["Tom Preston-Werner"] - gem.add_development_dependency "thoughtbot-shoulda" + gem.add_dependency('erlectricity', '>= 1.0.1') + gem.add_development_dependency("thoughtbot-shoulda") # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings end rescue LoadError diff --git a/lib/bert.rb b/lib/bert.rb index e69de29..1dc7180 100644 --- a/lib/bert.rb +++ b/lib/bert.rb @@ -0,0 +1,15 @@ +require 'rubygems' +require 'erlectricity' + +require 'bert/encoder' +require 'bert/decoder' + +module BERT + def self.encode(ruby) + Encoder.encode(ruby) + end + + def self.decode(bert) + Decoder.decode(bert) + end +end \ No newline at end of file diff --git a/lib/bert/decoder.rb b/lib/bert/decoder.rb new file mode 100644 index 0000000..3570272 --- /dev/null +++ b/lib/bert/decoder.rb @@ -0,0 +1,34 @@ +module BERT + class Decoder + # Decode a BERT into a Ruby object. + # +bert+ is the BERT String + # + # Returns a Ruby object + def self.decode(bert) + simple_ruby = Erlectricity::Decoder.decode(bert) + convert(simple_ruby) + end + + # Convert Erlectricity representation of BERT complex types into + # corresponding Ruby types. + # +item+ is the Ruby object to convert + # + # Returns the converted Ruby object + def self.convert(item) + case item + when [:nil, :nil] + nil + when Array + if item.first == :dict + item[1..-1].inject({}) do |acc, x| + acc[convert(x[0])] = convert(x[1]); acc + end + else + item.map { |x| convert(x) } + end + else + item + end + end + end +end \ No newline at end of file diff --git a/lib/bert/encoder.rb b/lib/bert/encoder.rb new file mode 100644 index 0000000..b354f11 --- /dev/null +++ b/lib/bert/encoder.rb @@ -0,0 +1,32 @@ +module BERT + class Encoder + # Encode a Ruby object into a BERT. + # +ruby+ is the Ruby object + # + # Returns a BERT + def self.encode(ruby) + complex_ruby = convert(ruby) + Erlectricity::Encoder.encode(complex_ruby) + end + + # Convert Ruby types into corresponding Erlectricity representation + # of BERT complex types. + # +item+ is the Ruby object to convert + # + # Returns the converted Ruby object + def self.convert(item) + case item + when Hash + a = [:dict] + item.each_pair { |k, v| a << [convert(k), convert(v)] } + a + when Array + item.map { |x| convert(x) } + when nil + [:nil, :nil] + else + item + end + end + end +end \ No newline at end of file diff --git a/test/bert_test.rb b/test/bert_test.rb index 1c46946..102f9b0 100644 --- a/test/bert_test.rb +++ b/test/bert_test.rb @@ -1,7 +1,17 @@ require 'test_helper' class BertTest < Test::Unit::TestCase - should "probably rename this file and start testing for real" do - flunk "hey buddy, you should probably rename this file and start testing for real" + context "BERT" do + should "encode" do + before = [:user, {:name => 'TPW', :nick => 'mojombo'}] + after = "\203h\002d\000\004userh\003d\000\004dicth\002d\000\004namem\000\000\000\003TPWh\002d\000\004nickm\000\000\000\amojombo" + assert_equal after, BERT.encode(before) + end + + should "decode" do + before = "\203h\002d\000\004userh\003d\000\004dicth\002d\000\004namem\000\000\000\003TPWh\002d\000\004nickm\000\000\000\amojombo" + after = [:user, {:name => 'TPW', :nick => 'mojombo'}] + assert_equal after, BERT.decode(before) + end end end diff --git a/test/decoder_test.rb b/test/decoder_test.rb new file mode 100644 index 0000000..f1cd672 --- /dev/null +++ b/test/decoder_test.rb @@ -0,0 +1,34 @@ +require 'test_helper' + +class DecoderTest < Test::Unit::TestCase + context "BERT Decoder complex type converter" do + should "convert nil" do + before = [:nil, :nil] + after = nil + assert_equal after, BERT::Decoder.convert(before) + end + + should "convert nested nil" do + before = [[:nil, :nil], [[:nil, :nil]]] + after = [nil, [nil]] + assert_equal after, BERT::Decoder.convert(before) + end + + should "convert hashes" do + before = [:dict, [:foo, 'bar']] + after = {:foo => 'bar'} + assert_equal after, BERT::Decoder.convert(before) + end + + should "convert nested hashes" do + before = [:dict, [:foo, [:dict, [:baz, 'bar']]]] + after = {:foo => {:baz => 'bar'}} + assert_equal after, BERT::Decoder.convert(before) + end + + should "leave other stuff alone" do + before = [1, 2.0, [:foo, 'bar']] + assert_equal before, BERT::Decoder.convert(before) + end + end +end diff --git a/test/encoder_test.rb b/test/encoder_test.rb new file mode 100644 index 0000000..ee06f5f --- /dev/null +++ b/test/encoder_test.rb @@ -0,0 +1,32 @@ +require 'test_helper' + +class EncoderTest < Test::Unit::TestCase + context "BERT Encoder complex type converter" do + should "convert nil" do + assert_equal [:nil, :nil], BERT::Encoder.convert(nil) + end + + should "convert nested nil" do + before = [nil, [nil]] + after = [[:nil, :nil], [[:nil, :nil]]] + assert_equal after, BERT::Encoder.convert(before) + end + + should "convert hashes" do + before = {:foo => 'bar'} + after = [:dict, [:foo, 'bar']] + assert_equal after, BERT::Encoder.convert(before) + end + + should "convert nested hashes" do + before = {:foo => {:baz => 'bar'}} + after = [:dict, [:foo, [:dict, [:baz, 'bar']]]] + assert_equal after, BERT::Encoder.convert(before) + end + + should "leave other stuff alone" do + before = [1, 2.0, [:foo, 'bar']] + assert_equal before, BERT::Encoder.convert(before) + end + end +end