-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
parser.rb
84 lines (72 loc) · 2.15 KB
/
parser.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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# frozen_string_literal: true
require 'base64'
require 'time'
module Aws
module Json
class Parser
include Seahorse::Model::Shapes
# @param [Seahorse::Model::ShapeRef] rules
def initialize(rules)
@rules = rules
end
# @param [String<JSON>] json
def parse(json, target = nil)
parse_ref(@rules, Json.load(json), target)
end
private
def structure(ref, values, target = nil)
shape = ref.shape
target = ref.shape.struct_class.new if target.nil?
values.each do |key, value|
member_name, member_ref = shape.member_by_location_name(key)
if member_ref
target[member_name] = parse_ref(member_ref, value)
elsif shape.union
target[:unknown] = { 'name' => key, 'value' => value }
end
end
if shape.union
# convert to subclass
member_subclass = shape.member_subclass(target.member).new
member_subclass[target.member] = target.value
target = member_subclass
end
target
end
def list(ref, values, target = nil)
target = [] if target.nil?
values.each do |value|
target << parse_ref(ref.shape.member, value)
end
target
end
def map(ref, values, target = nil)
target = {} if target.nil?
values.each do |key, value|
target[key] = parse_ref(ref.shape.value, value)
end
target
end
def parse_ref(ref, value, target = nil)
if value.nil?
nil
else
case ref.shape
when StructureShape then structure(ref, value, target)
when ListShape then list(ref, value, target)
when MapShape then map(ref, value, target)
when TimestampShape then time(value)
when BlobShape then Base64.decode64(value)
when BooleanShape then value.to_s == 'true'
else value
end
end
end
# @param [String, Integer] value
# @return [Time]
def time(value)
value.is_a?(Numeric) ? Time.at(value) : Time.parse(value)
end
end
end
end