Class: Odin::Validation::SchemaSerializer
- Inherits:
-
Object
- Object
- Odin::Validation::SchemaSerializer
- Defined in:
- lib/odin/validation/schema_serializer.rb
Instance Method Summary collapse
-
#serialize(schema) ⇒ Object
Serialize an OdinSchema back to ODIN text.
Instance Method Details
#serialize(schema) ⇒ Object
Serialize an OdinSchema back to ODIN text
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 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/odin/validation/schema_serializer.rb', line 9 def serialize(schema) lines = [] # 1. Metadata header unless schema..empty? lines << "{$}" schema..each do |key, value| lines << "#{key} = \"#{escape_string(value.to_s)}\"" end lines << "" end # 2. Import directives schema.imports.each do |imp| if imp.alias_name lines << "@import \"#{imp.path}\" as #{imp.alias_name}" else lines << "@import \"#{imp.path}\"" end end lines << "" unless schema.imports.empty? # 3. Type definitions schema.types.each do |type_name, schema_type| lines << "{@#{type_name}}" # Composition if schema_type.composition lines << "= #{schema_type.composition}" end schema_type.fields.each do |field_name, field| lines << serialize_field(field_name, field) end # Object constraints for this type if schema.object_constraints[type_name] schema.object_constraints[type_name].each do |constraint| lines << serialize_object_constraint(constraint) end end lines << "" end # 4. Root fields unless schema.fields.empty? # Group by section root_fields = {} sectioned_fields = Hash.new { |h, k| h[k] = {} } schema.fields.each do |path, field| parts = path.split(".", 2) if parts.length > 1 sectioned_fields[parts[0]][parts[1]] = field else root_fields[path] = field end end root_fields.each do |name, field| lines << serialize_field(name, field) end lines << "" unless root_fields.empty? sectioned_fields.each do |section, fields| lines << "{#{section}}" fields.each do |name, field| lines << serialize_field(name, field) end if schema.object_constraints[section] schema.object_constraints[section].each do |constraint| lines << serialize_object_constraint(constraint) end end lines << "" end end # 5. Array definitions schema.arrays.each do |array_path, schema_array| header = "{#{array_path}[]" if schema_array.columns && !schema_array.columns.empty? header += " : #{schema_array.columns.join(', ')}" end header += "}" lines << header # Array-level constraints bounds_parts = [] if schema_array.min_items || schema_array.max_items min_str = schema_array.min_items&.to_s || "" max_str = schema_array.max_items&.to_s || "" bounds_parts << ":(#{min_str}..#{max_str})" end bounds_parts << ":unique" if schema_array.unique lines << bounds_parts.join("") unless bounds_parts.empty? schema_array.item_fields.each do |field_name, field| lines << serialize_field(field_name, field) end if schema.object_constraints[array_path] schema.object_constraints[array_path].each do |constraint| lines << serialize_object_constraint(constraint) end end lines << "" end # 6. Orphan object constraints (not already output with types/fields/arrays) outputted_scopes = Set.new schema.types.each_key { |k| outputted_scopes.add(k) } schema.arrays.each_key { |k| outputted_scopes.add(k) } # Sectioned fields schema.fields.each_key do |path| parts = path.split(".", 2) outputted_scopes.add(parts[0]) if parts.length > 1 end outputted_scopes.add("") # root constraints handled inline schema.object_constraints.each do |scope, constraints| next if outputted_scopes.include?(scope) lines << "{#{scope}}" unless scope.empty? constraints.each do |constraint| lines << serialize_object_constraint(constraint) end lines << "" end lines.join("\n").rstrip + "\n" end |