string-keys-to-int: converting string keys into integers.
This commit is contained in:
parent
c094ed7dfb
commit
331d918190
10
README.md
10
README.md
@ -25,3 +25,13 @@ json-to-cbor < file.json > file.cbor
|
||||
hs < file.cbor
|
||||
```
|
||||
|
||||
# string-keys-to-int usage
|
||||
|
||||
JSON format has a limitation on the type of hash keys: it has to be a string.
|
||||
CBOR doesn't come with such limitation.
|
||||
`string-keys-to-int` automatically converts string keys into integers, whenever all the keys in a hash can be converted.
|
||||
|
||||
```sh
|
||||
string-keys-to-int < file.cbor
|
||||
```
|
||||
|
||||
|
@ -14,6 +14,8 @@ targets:
|
||||
main: src/json-to-cbor.cr
|
||||
hs:
|
||||
main: src/hs.cr
|
||||
string-keys-to-int:
|
||||
main: src/string-keys-to-int.cr
|
||||
bm-json-vs-cbor:
|
||||
main: tests/json-vs-cbor.cr
|
||||
|
||||
|
89
src/string-keys-to-int.cr
Normal file
89
src/string-keys-to-int.cr
Normal file
@ -0,0 +1,89 @@
|
||||
require "cbor"
|
||||
require "option_parser"
|
||||
|
||||
class Context
|
||||
class_property debug = false
|
||||
end
|
||||
|
||||
OptionParser.parse do |parser|
|
||||
parser.banner = "usage: string-keys-to-int < file.cbor"
|
||||
|
||||
parser.on "-d", "--debug",
|
||||
"Debug: print keys to convert, input and output data." do
|
||||
Context.debug = true
|
||||
end
|
||||
|
||||
parser.on "-h", "--help", "Displays this help and exits." do
|
||||
puts parser
|
||||
exit 0
|
||||
end
|
||||
end
|
||||
|
||||
def are_hash_keys_all_int?(data)
|
||||
case d = data
|
||||
when Hash
|
||||
keys = d.keys
|
||||
if keys.all? {|v| v.is_a?(String) }
|
||||
keys.all? {|v| v.as(String).to_i64 rescue false }
|
||||
else
|
||||
false
|
||||
end
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def change(data)
|
||||
# 1. change keys
|
||||
if are_hash_keys_all_int? data
|
||||
if Context.debug
|
||||
puts "keys to convert: #{data.as(Hash).keys}"
|
||||
end
|
||||
|
||||
# Do something
|
||||
case d = data
|
||||
when Hash
|
||||
keys = d.keys
|
||||
keys.each do |k|
|
||||
d[k.as(String).to_i32] = d[k]
|
||||
d.delete k
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# 2. dig
|
||||
case d = data
|
||||
when Hash
|
||||
keys = d.keys
|
||||
keys.each do |k|
|
||||
change d[k]
|
||||
end
|
||||
end
|
||||
rescue e
|
||||
STDERR.puts "something went wrong: #{e}"
|
||||
end
|
||||
|
||||
buffer = Bytes.new 1_000_000 # 1 MB
|
||||
|
||||
until STDIN.read(buffer) == 0
|
||||
decoder = CBOR::Decoder.new(buffer)
|
||||
while data = decoder.read_value
|
||||
break if data == 0
|
||||
|
||||
if Context.debug
|
||||
puts "input data:"
|
||||
pp data
|
||||
end
|
||||
|
||||
change data
|
||||
|
||||
if Context.debug
|
||||
puts "output data:"
|
||||
pp data
|
||||
else
|
||||
STDOUT.write data.to_cbor
|
||||
STDOUT.flush
|
||||
end
|
||||
end
|
||||
buffer = Bytes.new 1_000_000 # 1 MB
|
||||
end
|
Loading…
Reference in New Issue
Block a user