-
Notifications
You must be signed in to change notification settings - Fork 0
/
siren.rb
64 lines (51 loc) · 1.4 KB
/
siren.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
require 'rubygems'
require 'treetop'
require 'eventful'
%w[ json json_query json_query_nodes
walker parser node reference
].each do |path|
require File.dirname(__FILE__) + '/siren/' + path
end
module Siren
VERSION = '0.1.0'
TYPE_FIELD = "type"
ID_FIELD = "id"
REF_FIELD = "$ref"
class JsonParser
include Siren::Walker
end
def self.parse(string, &block)
@json_parser ||= JsonParser.new
Reference.flush!
@symbols = {}
result = @json_parser.parse(string).value rescue nil
@json_parser.walk(result) do |holder, key, value|
if Hash === value && value[REF_FIELD]
value = Reference.new(value)
value.on(:resolve) do |ref, root, symbols|
holder[key] = ref.find(root, symbols, holder)
end
end
value
end
@json_parser.walk(result) do |holder, key, value|
if Hash === value
id = value[ID_FIELD]
value = Node.from_json(value)
@symbols[id] = value
end
value
end
Reference.resolve!(result, @symbols)
@json_parser.walk(result, &block) if block_given?
result
end
def self.query(expression, root)
compile_query(expression).value(root, @symbols || {})
end
def self.compile_query(expression)
@query_parser ||= JsonQueryParser.new
@query_cache ||= {}
@query_cache[expression] ||= @query_parser.parse(expression)
end
end