protojson 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -3
- data/README.md +24 -19
- data/Rakefile +10 -8
- data/examples/addressbook.pb.rb +70 -0
- data/examples/addressbook.proto +37 -0
- data/examples/addressbook2.pb.rb +56 -0
- data/examples/example.rb +54 -0
- data/examples/main.rb +50 -0
- data/{spec → examples}/person +0 -0
- data/examples/repeated.pb.rb +32 -0
- data/examples/repeated.proto +12 -0
- data/examples/simple.pb.rb +23 -0
- data/examples/simple.proto +7 -0
- data/lib/protojson.rb +81 -3
- data/lib/protojson/codec/binary.rb +21 -0
- data/lib/protojson/codec/codec_interface.rb +15 -0
- data/lib/protojson/codec/hash.rb +121 -0
- data/lib/protojson/codec/json.rb +24 -0
- data/lib/protojson/codec/json_indexed.rb +85 -0
- data/lib/protojson/codec/json_tag_map.rb +25 -0
- data/lib/protojson/version.rb +1 -1
- data/protojson.gemspec +17 -10
- data/spec/codec_binary_spec.rb +150 -0
- data/spec/codec_json_hash_tag_spec.rb +179 -0
- data/spec/codec_json_indexed_spec.rb +182 -0
- data/spec/codec_json_spec.rb +153 -0
- data/spec/codecs_registry_spec.rb +85 -0
- metadata +75 -18
- data/spec/main.rb +0 -55
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -12,7 +12,7 @@ This gem extends the *ruby_protobuf* gem [1] to allow these new encodings in a p
|
|
12
12
|
|
13
13
|
# Installation
|
14
14
|
|
15
|
-
gem install protojson
|
15
|
+
gem install protojson -v0.2.0
|
16
16
|
|
17
17
|
# Supported formats
|
18
18
|
|
@@ -30,32 +30,37 @@ as a string, where each character represents a tag, and placing it as the first
|
|
30
30
|
|
31
31
|
## Serialize a message
|
32
32
|
|
33
|
-
require 'addressbook.pb'
|
34
|
-
require 'protojson'
|
35
|
-
person = Tutorial::Person.new
|
36
|
-
person.parse_from_file ARGV[0]
|
37
|
-
|
38
|
-
Protobuf::Message::encoding = Protobuf::Message::EncodingType::INDEXED
|
39
33
|
|
40
|
-
|
34
|
+
require 'protojson'
|
35
|
+
require 'examples/addressbook.rb'
|
41
36
|
|
42
|
-
|
37
|
+
book = Examples::AddressBook.new
|
43
38
|
|
44
|
-
|
39
|
+
person = Examples::Person.new
|
40
|
+
person.name = 'Juan de Bravo'
|
41
|
+
person.id = 21
|
42
|
+
book.person << person
|
45
43
|
|
46
|
-
|
47
|
-
require 'protojson'
|
44
|
+
### Serialize using the default codec (binary)
|
48
45
|
|
49
|
-
|
50
|
-
person.parse_from_file ARGV[0]
|
46
|
+
data = Protojson.encode(book)
|
51
47
|
|
52
|
-
|
48
|
+
### Serialize using a specific codec
|
53
49
|
|
54
|
-
|
50
|
+
[:json, :tagmap, :indexed].each{|codec|
|
51
|
+
Protojson.encode(book, codec)
|
52
|
+
}
|
55
53
|
|
56
|
-
|
54
|
+
## Unserialize a message
|
57
55
|
|
58
|
-
|
56
|
+
### Unserialize using a specific codec
|
57
|
+
data = Protojson.encode(book, :json)
|
58
|
+
value = Protojson.decode(Examples::AddressBook, data, :json)
|
59
|
+
puts value.person[0].name # "Juan de Bravo"
|
59
60
|
|
60
|
-
|
61
|
+
### Unserialize using the default codec
|
62
|
+
Protojson.set_default_codec(:json)
|
63
|
+
data = Protojson.encode(book)
|
64
|
+
value = Protojson.decode(Examples::AddressBook, data)
|
65
|
+
puts value.person[0].name # "Juan de Bravo"
|
61
66
|
|
data/Rakefile
CHANGED
@@ -1,20 +1,22 @@
|
|
1
1
|
require 'bundler'
|
2
|
-
require '
|
2
|
+
require 'rspec/core/rake_task'
|
3
3
|
require 'rake/clean'
|
4
4
|
|
5
5
|
Bundler::GemHelper.install_tasks
|
6
6
|
|
7
|
+
task :default => [:test]
|
8
|
+
|
9
|
+
RSpec::Core::RakeTask.new(:test) do |spec|
|
10
|
+
spec.skip_bundler = true
|
11
|
+
spec.pattern = 'spec/*_spec.rb'
|
12
|
+
spec.rspec_opts = '--color --format doc'
|
13
|
+
end
|
14
|
+
|
7
15
|
desc "Show the different encodings using a test file"
|
8
16
|
namespace :test do
|
9
17
|
task :person do
|
10
|
-
sh "ruby
|
18
|
+
sh "ruby examples/main.rb examples/person"
|
11
19
|
end
|
12
20
|
end
|
13
21
|
|
14
22
|
|
15
|
-
Rake::RDocTask.new do |rd|
|
16
|
-
rd.main = "README.md"
|
17
|
-
rd.rdoc_files.include("README.md", "LICENSE", "lib/**/*.rb")
|
18
|
-
rd.title = 'ProtoJson'
|
19
|
-
end
|
20
|
-
|
@@ -0,0 +1,70 @@
|
|
1
|
+
### Generated by rprotoc. DO NOT EDIT!
|
2
|
+
### <proto file: addressbook.proto>
|
3
|
+
# package examples;
|
4
|
+
#
|
5
|
+
# /**
|
6
|
+
# * Defines a Person in the addressbook
|
7
|
+
# */
|
8
|
+
# message Person {
|
9
|
+
# /* The full name of the person */
|
10
|
+
# required string name = 1;
|
11
|
+
# /* The person Id in the database */
|
12
|
+
# required int32 id = 2;
|
13
|
+
# /* The person email */
|
14
|
+
# optional string email = 3;
|
15
|
+
#
|
16
|
+
# /* Different types of phones */
|
17
|
+
# enum PhoneType {
|
18
|
+
# MOBILE = 0;
|
19
|
+
# HOME = 1;
|
20
|
+
# WORK = 2;
|
21
|
+
# }
|
22
|
+
#
|
23
|
+
# /* A phone number record */
|
24
|
+
# message PhoneNumber {
|
25
|
+
# required string number = 1;
|
26
|
+
# optional PhoneType type = 2 [default = HOME];
|
27
|
+
# }
|
28
|
+
#
|
29
|
+
# /* The different phone numbers associated to a person */
|
30
|
+
# repeated PhoneNumber phone = 4;
|
31
|
+
# }
|
32
|
+
#
|
33
|
+
#
|
34
|
+
# /* A collection of persons contact details */
|
35
|
+
# message AddressBook {
|
36
|
+
# repeated Person person = 1;
|
37
|
+
#
|
38
|
+
# extensions 1000 to max;
|
39
|
+
# }
|
40
|
+
|
41
|
+
require 'protobuf/message/message'
|
42
|
+
require 'protobuf/message/enum'
|
43
|
+
require 'protobuf/message/service'
|
44
|
+
require 'protobuf/message/extend'
|
45
|
+
|
46
|
+
module Examples
|
47
|
+
class Person < ::Protobuf::Message
|
48
|
+
defined_in __FILE__
|
49
|
+
required :string, :name, 1
|
50
|
+
required :int32, :id, 2
|
51
|
+
optional :string, :email, 3
|
52
|
+
class PhoneType < ::Protobuf::Enum
|
53
|
+
defined_in __FILE__
|
54
|
+
MOBILE = value(:MOBILE, 0)
|
55
|
+
HOME = value(:HOME, 1)
|
56
|
+
WORK = value(:WORK, 2)
|
57
|
+
end
|
58
|
+
class PhoneNumber < ::Protobuf::Message
|
59
|
+
defined_in __FILE__
|
60
|
+
required :string, :number, 1
|
61
|
+
optional :PhoneType, :type, 2, :default => :HOME
|
62
|
+
end
|
63
|
+
repeated :PhoneNumber, :phone, 4
|
64
|
+
end
|
65
|
+
class AddressBook < ::Protobuf::Message
|
66
|
+
defined_in __FILE__
|
67
|
+
repeated :Person, :person, 1
|
68
|
+
extensions 1000..::Protobuf::Extend::MAX
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
package examples;
|
2
|
+
|
3
|
+
/**
|
4
|
+
* Defines a Person in the addressbook
|
5
|
+
*/
|
6
|
+
message Person {
|
7
|
+
/* The full name of the person */
|
8
|
+
required string name = 1;
|
9
|
+
/* The person Id in the database */
|
10
|
+
required int32 id = 2;
|
11
|
+
/* The person email */
|
12
|
+
optional string email = 3;
|
13
|
+
|
14
|
+
/* Different types of phones */
|
15
|
+
enum PhoneType {
|
16
|
+
MOBILE = 0;
|
17
|
+
HOME = 1;
|
18
|
+
WORK = 2;
|
19
|
+
}
|
20
|
+
|
21
|
+
/* A phone number record */
|
22
|
+
message PhoneNumber {
|
23
|
+
required string number = 1;
|
24
|
+
optional PhoneType type = 2 [default = HOME];
|
25
|
+
}
|
26
|
+
|
27
|
+
/* The different phone numbers associated to a person */
|
28
|
+
repeated PhoneNumber phone = 4;
|
29
|
+
}
|
30
|
+
|
31
|
+
|
32
|
+
/* A collection of persons contact details */
|
33
|
+
message AddressBook {
|
34
|
+
repeated Person person = 1;
|
35
|
+
|
36
|
+
extensions 1000 to max;
|
37
|
+
}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
### Generated by rprotoc. DO NOT EDIT!
|
2
|
+
### <proto file: examples/addressbook.proto>
|
3
|
+
# package tutorial;
|
4
|
+
#
|
5
|
+
# message Person {
|
6
|
+
# required string name = 1;
|
7
|
+
# required int32 id = 2;
|
8
|
+
# optional string email = 3;
|
9
|
+
#
|
10
|
+
# enum PhoneType {
|
11
|
+
# MOBILE = 0;
|
12
|
+
# HOME = 1;
|
13
|
+
# WORK = 2;
|
14
|
+
# }
|
15
|
+
#
|
16
|
+
# message PhoneNumber {
|
17
|
+
# required string number = 1;
|
18
|
+
# optional PhoneType type = 2 [default = HOME];
|
19
|
+
# }
|
20
|
+
#
|
21
|
+
# repeated PhoneNumber phone = 4;
|
22
|
+
# }
|
23
|
+
#
|
24
|
+
# message AddressBook {
|
25
|
+
# repeated Person person = 1;
|
26
|
+
# }
|
27
|
+
|
28
|
+
require 'protobuf/message/message'
|
29
|
+
require 'protobuf/message/enum'
|
30
|
+
require 'protobuf/message/service'
|
31
|
+
require 'protobuf/message/extend'
|
32
|
+
|
33
|
+
module Tutorial
|
34
|
+
class Person < ::Protobuf::Message
|
35
|
+
defined_in __FILE__
|
36
|
+
required :string, :name, 1
|
37
|
+
required :int32, :id, 2
|
38
|
+
optional :string, :email, 3
|
39
|
+
class PhoneType < ::Protobuf::Enum
|
40
|
+
defined_in __FILE__
|
41
|
+
MOBILE = 0
|
42
|
+
HOME = 1
|
43
|
+
WORK = 2
|
44
|
+
end
|
45
|
+
class PhoneNumber < ::Protobuf::Message
|
46
|
+
defined_in __FILE__
|
47
|
+
required :string, :number, 1
|
48
|
+
optional :PhoneType, :type, 2, :default => :HOME
|
49
|
+
end
|
50
|
+
repeated :PhoneNumber, :phone, 4
|
51
|
+
end
|
52
|
+
class AddressBook < ::Protobuf::Message
|
53
|
+
defined_in __FILE__
|
54
|
+
repeated :Person, :person, 1
|
55
|
+
end
|
56
|
+
end
|
data/examples/example.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
2
|
+
$:.unshift File.join(File.dirname(__FILE__), '.')
|
3
|
+
|
4
|
+
require 'addressbook.pb'
|
5
|
+
require 'protojson'
|
6
|
+
|
7
|
+
book = Examples::AddressBook.new
|
8
|
+
person = Examples::Person.new
|
9
|
+
person.name = 'John Doe'
|
10
|
+
person.id = 2051
|
11
|
+
person.email = "john.doe@gmail.com"
|
12
|
+
phone = Examples::Person::PhoneNumber.new
|
13
|
+
phone.number = '1231231212'
|
14
|
+
phone.type = Examples::Person::PhoneType::HOME
|
15
|
+
person.phone << phone
|
16
|
+
phone = Examples::Person::PhoneNumber.new
|
17
|
+
phone.number = '55512321312'
|
18
|
+
phone.type = Examples::Person::PhoneType::MOBILE
|
19
|
+
person.phone << phone
|
20
|
+
book.person << person
|
21
|
+
|
22
|
+
person = Examples::Person.new
|
23
|
+
person.name = "Ivan Montes"
|
24
|
+
person.id = 23
|
25
|
+
person.email = "drslump@pollinimini.net"
|
26
|
+
phone = Examples::Person::PhoneNumber.new
|
27
|
+
phone.number = '3493123123'
|
28
|
+
phone.type = Examples::Person::PhoneType::WORK
|
29
|
+
person.phone << phone
|
30
|
+
book.person << person
|
31
|
+
|
32
|
+
person = Examples::Person.new
|
33
|
+
person.name = "Juan de Bravo"
|
34
|
+
person.id = 24
|
35
|
+
person.email = "juan@pollinimini.net"
|
36
|
+
phone = Examples::Person::PhoneNumber.new
|
37
|
+
phone.number = '3493123124'
|
38
|
+
phone.type = Examples::Person::PhoneType::WORK
|
39
|
+
person.phone << phone
|
40
|
+
book.person << person
|
41
|
+
|
42
|
+
puts "\nAddressbook info:\n"
|
43
|
+
|
44
|
+
p book
|
45
|
+
|
46
|
+
puts "\nJSON encoding: \n"
|
47
|
+
puts Protojson.encode(book, :json)
|
48
|
+
|
49
|
+
puts "\nTAGMAP encoding: \n"
|
50
|
+
puts Protojson.encode(book, :tag_map)
|
51
|
+
|
52
|
+
puts "\nINDEXED encoding: \n"
|
53
|
+
puts Protojson.encode(book, :indexed).to_s
|
54
|
+
|
data/examples/main.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
|
2
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__),'.')
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'addressbook2.pb'
|
7
|
+
require 'protojson'
|
8
|
+
|
9
|
+
unless ARGV.size == 1
|
10
|
+
puts "Usage: #{$0} ADDRESS_BOOK_FILE"
|
11
|
+
exit
|
12
|
+
end
|
13
|
+
|
14
|
+
person = Tutorial::Person.new
|
15
|
+
person.parse_from_file ARGV[0]
|
16
|
+
|
17
|
+
puts ""
|
18
|
+
puts "Person data"
|
19
|
+
puts "..........."
|
20
|
+
|
21
|
+
p person
|
22
|
+
|
23
|
+
puts ""
|
24
|
+
puts "Json encoding"
|
25
|
+
puts "................"
|
26
|
+
value = Protojson.encode(person, Protojson::Codec::Json)
|
27
|
+
puts value
|
28
|
+
person = Protojson.decode(Tutorial::Person, value, :json)
|
29
|
+
|
30
|
+
puts ""
|
31
|
+
puts "Indexed encoding"
|
32
|
+
puts "................"
|
33
|
+
value = Protojson.encode(person, Protojson::Codec::JsonIndexed)
|
34
|
+
p value
|
35
|
+
person = Protojson.decode(Tutorial::Person, value, :indexed)
|
36
|
+
|
37
|
+
puts ""
|
38
|
+
puts "Tagmap encoding"
|
39
|
+
puts "..............."
|
40
|
+
value = Protojson.encode(person, Protojson::Codec::JsonTagMap)
|
41
|
+
puts value
|
42
|
+
person = Protojson.decode(Tutorial::Person, value, :tag_map)
|
43
|
+
|
44
|
+
puts ""
|
45
|
+
puts "Hashmap encoding"
|
46
|
+
puts "................"
|
47
|
+
value = Protojson.encode(person, Protojson::Codec::Hash)
|
48
|
+
puts value
|
49
|
+
person = Protojson.decode(Tutorial::Person, value, :hash)
|
50
|
+
|
data/{spec → examples}/person
RENAMED
File without changes
|
@@ -0,0 +1,32 @@
|
|
1
|
+
### Generated by rprotoc. DO NOT EDIT!
|
2
|
+
### <proto file: repeated.proto>
|
3
|
+
# package examples;
|
4
|
+
#
|
5
|
+
# message Repeated {
|
6
|
+
#
|
7
|
+
# message Nested {
|
8
|
+
# optional int32 id = 1;
|
9
|
+
# }
|
10
|
+
#
|
11
|
+
# repeated string string = 1;
|
12
|
+
# repeated int32 int = 2;
|
13
|
+
# repeated Nested nested = 3;
|
14
|
+
# }
|
15
|
+
|
16
|
+
require 'protobuf/message/message'
|
17
|
+
require 'protobuf/message/enum'
|
18
|
+
require 'protobuf/message/service'
|
19
|
+
require 'protobuf/message/extend'
|
20
|
+
|
21
|
+
module Examples
|
22
|
+
class Repeated < ::Protobuf::Message
|
23
|
+
defined_in __FILE__
|
24
|
+
class Nested < ::Protobuf::Message
|
25
|
+
defined_in __FILE__
|
26
|
+
optional :int32, :id, 1
|
27
|
+
end
|
28
|
+
repeated :string, :string, 1
|
29
|
+
repeated :int32, :int, 2
|
30
|
+
repeated :Nested, :nested, 3
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
### Generated by rprotoc. DO NOT EDIT!
|
2
|
+
### <proto file: simple.proto>
|
3
|
+
# package examples;
|
4
|
+
#
|
5
|
+
# message Simple {
|
6
|
+
# required string foo = 1;
|
7
|
+
# required int32 bar = 2;
|
8
|
+
# optional string baz = 3;
|
9
|
+
# }
|
10
|
+
|
11
|
+
require 'protobuf/message/message'
|
12
|
+
require 'protobuf/message/enum'
|
13
|
+
require 'protobuf/message/service'
|
14
|
+
require 'protobuf/message/extend'
|
15
|
+
|
16
|
+
module Examples
|
17
|
+
class Simple < ::Protobuf::Message
|
18
|
+
defined_in __FILE__
|
19
|
+
required :string, :foo, 1
|
20
|
+
required :int32, :bar, 2
|
21
|
+
optional :string, :baz, 3
|
22
|
+
end
|
23
|
+
end
|