diff --git a/README.md b/README.md index a2e74c9..9f39ba7 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,30 @@ Command-line tool to encode and decode arbitrary protobuf data. + +## Installation + +This program requires Crystal. See: https://crystal-lang.org/install/ + +### Standalone + +1. Clone: `git clone https://github.com/iv-org/protodec && cd protodec` +2. Build: `crystal build src/protodec.cr` +3. See [Usage](#Usage) below + + +### As a Crystal library + +Add this to your application's `shard.yml`: + +```yaml +dependencies: + protodec: + github: iv-org/protodec + version: ~> 0.1.5 +``` + + ## Usage ``` @@ -57,9 +81,13 @@ $ echo 'CkEKCeOCj+OBn+OBlxDSCSIQWmQ730+N8z8tsp3vp8YJQCoSCAESBzA4MDAwMDAaBQ26sSZE } ``` +## Windows + +Windows users can run the binaries in a linux-on-windows tool (like Git bash or WSL) or use the official [protobuf binaries](https://github.com/protocolbuffers/protobuf/releases) to encode/decode protobuf data. + ## Contributing -1. Fork it () +1. Fork it () 2. Create your feature branch (`git checkout -b my-new-feature`) 3. Commit your changes (`git commit -am 'Add some feature'`) 4. Push to the branch (`git push origin my-new-feature`) diff --git a/shard.yml b/shard.yml index 67f01b8..33c49db 100644 --- a/shard.yml +++ b/shard.yml @@ -1,13 +1,14 @@ name: protodec -version: 0.1.1 +version: 0.1.5 authors: - Omar Roth + - Invidous team targets: protodec: main: src/protodec.cr -crystal: 0.31.1 +crystal: ">= 0.34.0, < 2.0.0" license: GPLv3 diff --git a/spec/protodec_spec.cr b/spec/protodec_spec.cr index 8575d4b..875161a 100644 --- a/spec/protodec_spec.cr +++ b/spec/protodec_spec.cr @@ -2,7 +2,7 @@ require "./spec_helper" describe Protodec do it "decodes Base64 data" do - input = "4qmFsgIrEhhVQ0NqOTU2SUY2MkZiVDdHb3VzemFqOXcaD0VnbGpiMjF0ZFc1cGRIaw" + input = "4qmFsgIsEhhVQ0NqOTU2SUY2MkZiVDdHb3VzemFqOXcaEEVnbGpiMjF0ZFc1cGRIaz0" output = input.strip .try { |i| URI.decode_www_form(i) } .try { |i| URI.decode_www_form(i) } @@ -24,6 +24,6 @@ describe Protodec do }, }) - Base64.urlsafe_encode(Protodec::Any.from_json(object), padding: false).should eq("4qmFsgIrEhhVQ0NqOTU2SUY2MkZiVDdHb3VzemFqOXcaD0VnbGpiMjF0ZFc1cGRIaw") + Base64.urlsafe_encode(Protodec::Any.from_json(object), padding: false).should eq("4qmFsgIsEhhVQ0NqOTU2SUY2MkZiVDdHb3VzemFqOXcaEEVnbGpiMjF0ZFc1cGRIaz0") end end diff --git a/src/protodec/utils.cr b/src/protodec/utils.cr index df9faf3..6c7c509 100644 --- a/src/protodec/utils.cr +++ b/src/protodec/utils.cr @@ -200,7 +200,7 @@ module Protodec from_json(value, buffer) buffer.rewind - buffer = Base64.urlsafe_encode(buffer, padding: false) + buffer = Base64.urlsafe_encode(buffer) VarLong.to_io(io, buffer.bytesize.to_i64) buffer.to_s(io) when "embedded" @@ -213,6 +213,9 @@ module Protodec when "bytes" VarLong.to_io(io, value.size.to_i64) value.as_a.each { |byte| io.write_byte byte.as_i.to_u8 } + else # "string" + VarLong.to_io(io, value.to_s.bytesize.to_i64) + io.print value.to_s end end else @@ -465,13 +468,22 @@ module Protodec Any.new(raw.clone) end - def self.cast_json(object) - raise "Invalid type" if !object.is_a?(Hash) - + def self.cast_json(object : Hash) JSON::Any.new(object.transform_values do |value| case value when .is_a?(Hash) cast_json(value) + when .is_a?(Protodec::Any) + case raw = value.raw + when Array(UInt8) + JSON::Any.new(raw.map { |i| JSON::Any.new(i.to_i64) }) + when Int32 + JSON::Any.new(raw.to_i64) + when Hash(String, Protodec::Any) + cast_json(raw) + else + JSON::Any.new(raw) + end else JSON::Any.new(value) end