|
|
|
@ -0,0 +1,129 @@
|
|
|
|
|
require "option_parser"
|
|
|
|
|
require "json"
|
|
|
|
|
require "cbor"
|
|
|
|
|
|
|
|
|
|
class Context
|
|
|
|
|
class_property is_json = false
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# # XXX
|
|
|
|
|
# class Action
|
|
|
|
|
# property command : Proc(v : JSON::Any | CBOR::Any, Bool)
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
|
|
class SelectApplication
|
|
|
|
|
property to_search = Array(String).new
|
|
|
|
|
|
|
|
|
|
def initialize
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def run
|
|
|
|
|
OptionParser.parse do |parser|
|
|
|
|
|
parser.banner = "usage: select [options] filters"
|
|
|
|
|
|
|
|
|
|
parser.on "-j", "--json", "Input is JSON." do
|
|
|
|
|
Context.is_json = true
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
parser.on "-h", "--help", "Displays this help and exits." do
|
|
|
|
|
puts parser
|
|
|
|
|
exit 0
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 1. Get intent from CLI.
|
|
|
|
|
if ARGV.size == 0
|
|
|
|
|
STDERR.puts "What do you want to do?"
|
|
|
|
|
STDERR.puts "usage: select [options] filters"
|
|
|
|
|
STDERR.puts "example: cat *.json | select -j '.size >= 100'"
|
|
|
|
|
exit 1
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 1.1 get rules and stuff.
|
|
|
|
|
intent = ARGV[0]
|
|
|
|
|
|
|
|
|
|
proc = case intent
|
|
|
|
|
# String comparison.
|
|
|
|
|
when /(?<attribute>[^ ]+)[ ]*(?<comparison>(eq|neq|=~)+)[ ]*(?<value>[^ ]+)/
|
|
|
|
|
attribute = $~["attribute"]
|
|
|
|
|
comparison = $~["comparison"]
|
|
|
|
|
value = $~["value"]
|
|
|
|
|
pp! "string comparison", attribute, comparison, value
|
|
|
|
|
|
|
|
|
|
->(v : JSON::Any | CBOR::Any) {
|
|
|
|
|
case comparison
|
|
|
|
|
when /neq/
|
|
|
|
|
puts "attribute #{attribute} shouldn't be equal to #{value}"
|
|
|
|
|
when /eq/
|
|
|
|
|
puts "attribute #{attribute} should be equal to #{value}"
|
|
|
|
|
when /=~/
|
|
|
|
|
puts "attribute #{attribute} should match #{value}"
|
|
|
|
|
else
|
|
|
|
|
raise "string comparison '#{comparison}' not understood"
|
|
|
|
|
end
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Numerical comparison.
|
|
|
|
|
when /(?<attribute>[^ ]+)[ ]*(?<comparison>[=<>]+)[ ]*(?<value>[^ ]+)/
|
|
|
|
|
attribute = $~["attribute"]
|
|
|
|
|
comparison = $~["comparison"]
|
|
|
|
|
value = $~["value"]
|
|
|
|
|
pp! "numerical comparison", attribute, comparison, value
|
|
|
|
|
|
|
|
|
|
->(v : JSON::Any | CBOR::Any) {
|
|
|
|
|
case comparison
|
|
|
|
|
when /!=/
|
|
|
|
|
puts "attribute #{attribute} shouldn't be equal to #{value}"
|
|
|
|
|
when /==/
|
|
|
|
|
puts "attribute #{attribute} should be equal to #{value}"
|
|
|
|
|
when />=/
|
|
|
|
|
puts "attribute #{attribute} should be greater or equal than #{value}"
|
|
|
|
|
when /<=/
|
|
|
|
|
puts "attribute #{attribute} should be less or equal than #{value}"
|
|
|
|
|
when />/
|
|
|
|
|
puts "attribute #{attribute} should be greater than #{value}"
|
|
|
|
|
when /</
|
|
|
|
|
puts "attribute #{attribute} should be less than #{value}"
|
|
|
|
|
else
|
|
|
|
|
raise "numerical comparison '#{comparison}' not understood"
|
|
|
|
|
end
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
STDERR.puts "cannot understand the intent of #{intent}"
|
|
|
|
|
exit 1
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
proc.call CBOR::Any.new "this is my attribute"
|
|
|
|
|
|
|
|
|
|
# TODO: FIXME
|
|
|
|
|
exit 0
|
|
|
|
|
|
|
|
|
|
buffer = Bytes.new 1_000_000 # 1 MB
|
|
|
|
|
decoder = CBOR::Decoder.new(buffer)
|
|
|
|
|
|
|
|
|
|
# 2. Get all input.
|
|
|
|
|
data = if Context.is_json
|
|
|
|
|
JSON.parse STDIN.gets_to_end
|
|
|
|
|
else
|
|
|
|
|
exit 0 if STDIN.read(buffer) == 0
|
|
|
|
|
v = decoder.read_value
|
|
|
|
|
exit 0 if v == 0 # FIXME: this is likely an error in the CBOR library.
|
|
|
|
|
v
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 2. TODO: oselect manipulations
|
|
|
|
|
result = if data.is_a?(JSON::Any)
|
|
|
|
|
data.to_json.to_slice
|
|
|
|
|
elsif data.is_a?(CBOR::Any)
|
|
|
|
|
data.to_cbor
|
|
|
|
|
else
|
|
|
|
|
STDERR.puts "data is neither JSON::Any or CBOR::Any"
|
|
|
|
|
exit 1
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
STDOUT.write result
|
|
|
|
|
STDOUT.flush
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
SelectApplication.new.run
|