90 lines
1.4 KiB
Crystal
90 lines
1.4 KiB
Crystal
|
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
|