11# frozen_string_literal: true
22
3- require_relative 'document_utilities '
3+ require_relative 'document_utils '
44
55module Smithy
66 module Schema
77 # TODO: need to address the following and more
88 # * documentation
99 class Document
10- include DocumentUtilities
11- def initialize ( data , schema = nil )
12- @data = format_data ( data , schema )
13- @discriminator = Extractor . discriminator ( data , schema )
14- @schema = schema
10+ def initialize ( data , options = { } )
11+ @data = set_data ( data , options )
12+ @discriminator = extract_discriminator ( data , options )
1513 end
1614
17- attr_reader :data , :discriminator , :schema
15+ attr_reader :data , :discriminator
1816
1917 def []( key )
2018 return unless @data . is_a? ( Hash ) && @data . key? ( key )
2119
2220 @data [ key ]
2321 end
2422
25- def as_typed ( schema )
23+ def as_typed ( schema , opts = { } )
2624 error_message = 'Invalid schema or document data'
2725 raise ArgumentError , error_message unless valid_schema? ( schema ) && @data . is_a? ( Hash )
2826
2927 type = schema . type . new
30- Applier . apply ( schema , @data , type )
28+ DocumentUtils . apply ( @data , schema , type , opts )
3129 end
3230
3331 private
@@ -36,22 +34,49 @@ def discriminator?(data)
3634 data . is_a? ( Hash ) && data . key? ( '__type' )
3735 end
3836
39- def format_data ( data , schema )
37+ def extract_discriminator ( data , opts )
38+ return if data . nil?
39+
40+ return unless discriminator? ( data ) || ( schema = opts [ :schema ] )
41+
42+ if discriminator? ( data )
43+ data [ '__type' ]
44+ else
45+ error_message = "Expected a structure schema, given #{ schema . class } instead"
46+ raise error_message unless valid_schema? ( schema )
47+
48+ schema . id
49+ end
50+ end
51+
52+ def set_data ( data , options )
4053 return if data . nil?
4154
4255 case data
4356 when Smithy ::Schema ::Structure
44- if schema . nil? || !schema . is_a? ( Shapes ::StructureShape )
45- raise ArgumentError , 'Unable to convert as document with given schema'
57+ schema = options [ :schema ]
58+ if schema . nil? || !valid_schema? ( schema )
59+ raise ArgumentError , "Unable to convert to document with given schema: #{ schema } "
4660 end
4761
48- Extractor . extract ( schema , data )
62+ options = options . except ( :schema )
63+ # case 1 - extract data from runtime shape, schema is required to know to properly extract
64+ DocumentUtils . extract ( data , schema , options )
65+
4966 else
50- data = data . except ( '__type' ) if discriminator? ( data )
51- data # TODO: add some validation if schema exists
67+ if discriminator? ( data )
68+ # case 2 - extract typed data from parsed JSON
69+ # Open question - if there is a schema given, should we validate that these
70+ # two pieces work together?
71+ data . except ( '__type' )
72+ else
73+ # case 3 - untyped data, we will need consolidate timestamps and such
74+ DocumentUtils . format ( data )
75+ end
5276 end
5377 end
5478
79+ # TODO: probably need to check if given runtime shape is a type of schema
5580 def valid_schema? ( schema )
5681 schema . is_a? ( Shapes ::StructureShape ) && !schema . type . nil?
5782 end
0 commit comments