avro-gen-ruby 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yml +34 -0
  3. data/.github/workflows/release.yml +31 -0
  4. data/.gitignore +6 -0
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +100 -0
  7. data/Gemfile +5 -0
  8. data/LICENSE +21 -0
  9. data/README.md +61 -0
  10. data/Rakefile +11 -0
  11. data/avro-gen-ruby.gemspec +32 -0
  12. data/lib/avro_gen/avro_parser.rb +64 -0
  13. data/lib/avro_gen/configuration.rb +60 -0
  14. data/lib/avro_gen/errors.rb +6 -0
  15. data/lib/avro_gen/generator/templates/schema_class.rb.tt +8 -0
  16. data/lib/avro_gen/generator/templates/schema_enum.rb.tt +13 -0
  17. data/lib/avro_gen/generator/templates/schema_record.rb.tt +102 -0
  18. data/lib/avro_gen/generator.rb +375 -0
  19. data/lib/avro_gen/railtie.rb +12 -0
  20. data/lib/avro_gen/schema_class/base.rb +62 -0
  21. data/lib/avro_gen/schema_class/enum.rb +48 -0
  22. data/lib/avro_gen/schema_class/record.rb +108 -0
  23. data/lib/avro_gen/schema_class.rb +62 -0
  24. data/lib/avro_gen/schema_field.rb +26 -0
  25. data/lib/avro_gen/schema_validator.rb +80 -0
  26. data/lib/avro_gen/upgrader.rb +43 -0
  27. data/lib/avro_gen/version.rb +5 -0
  28. data/lib/avro_gen.rb +18 -0
  29. data/lib/tasks/avro.rake +18 -0
  30. data/regenerate_test_schema_classes.rb +32 -0
  31. data/spec/generator_spec.rb +92 -0
  32. data/spec/my_schema_spec.rb +18 -0
  33. data/spec/my_schema_with_circular_reference_spec.rb +97 -0
  34. data/spec/my_schema_with_complex_types_spec.rb +235 -0
  35. data/spec/schema_validator_spec.rb +42 -0
  36. data/spec/schemas/com/my-namespace/Generated.avsc +77 -0
  37. data/spec/schemas/com/my-namespace/MyNestedSchema.avsc +62 -0
  38. data/spec/schemas/com/my-namespace/MySchema.avsc +18 -0
  39. data/spec/schemas/com/my-namespace/MySchemaCompound_key.avsc +18 -0
  40. data/spec/schemas/com/my-namespace/MySchemaId_key.avsc +12 -0
  41. data/spec/schemas/com/my-namespace/MySchemaWithBooleans.avsc +18 -0
  42. data/spec/schemas/com/my-namespace/MySchemaWithCircularReference.avsc +39 -0
  43. data/spec/schemas/com/my-namespace/MySchemaWithComplexTypes.avsc +120 -0
  44. data/spec/schemas/com/my-namespace/MySchemaWithDateTimes.avsc +33 -0
  45. data/spec/schemas/com/my-namespace/MySchemaWithId.avsc +28 -0
  46. data/spec/schemas/com/my-namespace/MySchemaWithTitle.avsc +22 -0
  47. data/spec/schemas/com/my-namespace/MySchemaWithUnionType.avsc +91 -0
  48. data/spec/schemas/com/my-namespace/MySchemaWithUniqueId.avsc +32 -0
  49. data/spec/schemas/com/my-namespace/MySchema_key.avsc +13 -0
  50. data/spec/schemas/com/my-namespace/Wibble.avsc +43 -0
  51. data/spec/schemas/com/my-namespace/Widget.avsc +27 -0
  52. data/spec/schemas/com/my-namespace/WidgetTheSecond.avsc +27 -0
  53. data/spec/schemas/com/my-namespace/WidgetTheThird.avsc +27 -0
  54. data/spec/schemas/com/my-namespace/my-suborg/MyLongNamespaceSchema.avsc +18 -0
  55. data/spec/schemas/com/my-namespace/request/CreateTopic.avsc +11 -0
  56. data/spec/schemas/com/my-namespace/request/Index.avsc +11 -0
  57. data/spec/schemas/com/my-namespace/request/UpdateRequest.avsc +11 -0
  58. data/spec/schemas/com/my-namespace/response/CreateTopic.avsc +11 -0
  59. data/spec/schemas/com/my-namespace/response/Index.avsc +11 -0
  60. data/spec/schemas/com/my-namespace/response/UpdateResponse.avsc +11 -0
  61. data/spec/schemas/my_namespace/generated.rb +164 -0
  62. data/spec/schemas/my_namespace/my_long_namespace_schema.rb +49 -0
  63. data/spec/schemas/my_namespace/my_nested_schema.rb +126 -0
  64. data/spec/schemas/my_namespace/my_schema.rb +62 -0
  65. data/spec/schemas/my_namespace/my_schema_compound_key.rb +42 -0
  66. data/spec/schemas/my_namespace/my_schema_id_key.rb +37 -0
  67. data/spec/schemas/my_namespace/my_schema_key.rb +37 -0
  68. data/spec/schemas/my_namespace/my_schema_with_boolean.rb +42 -0
  69. data/spec/schemas/my_namespace/my_schema_with_circular_reference.rb +84 -0
  70. data/spec/schemas/my_namespace/my_schema_with_complex_type.rb +241 -0
  71. data/spec/schemas/my_namespace/my_schema_with_date_time.rb +57 -0
  72. data/spec/schemas/my_namespace/my_schema_with_id.rb +52 -0
  73. data/spec/schemas/my_namespace/my_schema_with_title.rb +47 -0
  74. data/spec/schemas/my_namespace/my_schema_with_union_type.rb +205 -0
  75. data/spec/schemas/my_namespace/my_schema_with_unique_id.rb +57 -0
  76. data/spec/schemas/my_namespace/request/create_topic.rb +37 -0
  77. data/spec/schemas/my_namespace/request/index.rb +37 -0
  78. data/spec/schemas/my_namespace/request/update_request.rb +37 -0
  79. data/spec/schemas/my_namespace/response/create_topic.rb +37 -0
  80. data/spec/schemas/my_namespace/response/index.rb +37 -0
  81. data/spec/schemas/my_namespace/response/update_response.rb +37 -0
  82. data/spec/schemas/my_namespace/wibble.rb +77 -0
  83. data/spec/schemas/my_namespace/widget.rb +57 -0
  84. data/spec/schemas/my_namespace/widget_the_second.rb +57 -0
  85. data/spec/schemas/my_namespace/widget_the_third.rb +57 -0
  86. data/spec/snapshots/consumers-no-nest.snap +1740 -0
  87. data/spec/snapshots/consumers.snap +1720 -0
  88. data/spec/snapshots/my_nested_schema.snap +121 -0
  89. data/spec/snapshots/my_schema_with_boolean.snap +44 -0
  90. data/spec/snapshots/my_schema_with_circular_reference.snap +81 -0
  91. data/spec/snapshots/my_schema_with_complex_type.snap +236 -0
  92. data/spec/snapshots/my_schema_with_date_time.snap +59 -0
  93. data/spec/snapshots/my_schema_with_union_type.snap +207 -0
  94. data/spec/snapshots/namespace_folders.snap +1800 -0
  95. data/spec/snapshots/namespace_map.snap +1800 -0
  96. data/spec/spec_helper.rb +23 -0
  97. metadata +265 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ba3c25a3781ca50da7273e62f05126ffe641538096cae34178161cae558a20ff
4
+ data.tar.gz: b8c25703ca1cda292d6fb50e2158a75a6b3b7a7dbe7109908fb55db129ab7545
5
+ SHA512:
6
+ metadata.gz: bee416615047e91d012ceb396a9249990fb748b8e951f13d7d5296a7b4d5ba36f2ff1a748974171fc0351b3df3ae8500e4bbb5551a0c334abfebe7300beaf741
7
+ data.tar.gz: c4c97a2939069802696506c370b4e72582dffa5d6b97f9cc8ba2d08e2c4840fe7d572ad7ed0790b9256c8c92d071b1f3e49907ed580bf4a8ec96461564425edd
@@ -0,0 +1,34 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [ main ]
7
+
8
+ jobs:
9
+ linting:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - name: Set up Ruby 3.3
14
+ uses: ruby/setup-ruby@v1
15
+ with:
16
+ ruby-version: 3.3
17
+ bundler-cache: true
18
+ - name: Rubocop
19
+ run: bundle exec rubocop --format progress
20
+
21
+ build:
22
+ runs-on: ubuntu-latest
23
+ strategy:
24
+ fail-fast: false
25
+ matrix:
26
+ ruby: [ '3.2', '3.3', '3.4', '4.0' ]
27
+ steps:
28
+ - uses: actions/checkout@v4
29
+ - uses: ruby/setup-ruby@v1
30
+ with:
31
+ ruby-version: ${{ matrix.ruby }}
32
+ bundler-cache: true
33
+ - name: Test
34
+ run: bundle exec rspec
@@ -0,0 +1,31 @@
1
+ name: Release Gem
2
+ on:
3
+ push:
4
+ branches:
5
+ - main
6
+ tags:
7
+ - 'v*.*.*' # Matches semantic versioning tags like v1.0.0
8
+ workflow_dispatch: # Allows manual triggering of the workflow
9
+
10
+ jobs:
11
+ push:
12
+ name: Push gem to RubyGems.org
13
+ runs-on: ubuntu-latest
14
+
15
+ permissions:
16
+ id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
17
+ contents: write # IMPORTANT: this permission is required for `rake release` to push the release tag
18
+
19
+ steps:
20
+ # Set up
21
+ - uses: actions/checkout@v4
22
+ with:
23
+ persist-credentials: false
24
+ - name: Set up Ruby
25
+ uses: ruby/setup-ruby@v1
26
+ with:
27
+ bundler-cache: true
28
+ ruby-version: ruby
29
+
30
+ # Release
31
+ - uses: rubygems/release-gem@v1
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ /.bundle/
2
+ /Gemfile.lock
3
+ /pkg/
4
+ /tmp/
5
+ /spec/app/
6
+ *.gem
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper --format documentation
data/.rubocop.yml ADDED
@@ -0,0 +1,100 @@
1
+ plugins:
2
+ - rubocop-rspec
3
+
4
+ AllCops:
5
+ TargetRubyVersion: 3.2
6
+ NewCops: enable
7
+ SuggestExtensions: false
8
+ Exclude:
9
+ - vendor/**/*
10
+ - spec/app/**/*
11
+ - spec/schemas/**/*
12
+ - spec/snapshots/**/*
13
+
14
+ Gemspec/DevelopmentDependencies:
15
+ EnforcedStyle: gemspec
16
+
17
+ Layout/AccessModifierIndentation:
18
+ EnforcedStyle: outdent
19
+
20
+ Layout/DotPosition:
21
+ EnforcedStyle: trailing
22
+
23
+ Layout/LineLength:
24
+ Max: 120
25
+
26
+ Layout/MultilineMethodCallIndentation:
27
+ EnforcedStyle: indented
28
+
29
+ Layout/SpaceAroundEqualsInParameterDefault:
30
+ EnforcedStyle: no_space
31
+
32
+ Lint/UnusedBlockArgument:
33
+ AllowUnusedKeywordArguments: true
34
+
35
+ Lint/UnusedMethodArgument:
36
+ AllowUnusedKeywordArguments: true
37
+
38
+ Lint/MissingSuper:
39
+ Enabled: false
40
+
41
+ Metrics:
42
+ Enabled: false
43
+
44
+ Style/Alias:
45
+ EnforcedStyle: prefer_alias_method
46
+
47
+ Style/ClassAndModuleChildren:
48
+ Enabled: false
49
+
50
+ Style/Documentation:
51
+ Enabled: false
52
+
53
+ Style/EmptyMethod:
54
+ EnforcedStyle: expanded
55
+
56
+ Style/IfUnlessModifier:
57
+ Enabled: false
58
+
59
+ Style/PercentLiteralDelimiters:
60
+ PreferredDelimiters:
61
+ '%i': '()'
62
+ '%I': '()'
63
+ '%w': '()'
64
+ '%W': '()'
65
+
66
+ Style/RedundantSelf:
67
+ Enabled: false
68
+
69
+ Style/StringLiterals:
70
+ EnforcedStyle: single_quotes
71
+
72
+ Style/SymbolArray:
73
+ EnforcedStyle: percent
74
+
75
+ RSpec/ExampleWording:
76
+ Enabled: false
77
+
78
+ RSpec/ExampleLength:
79
+ Enabled: false
80
+
81
+ RSpec/MultipleExpectations:
82
+ Enabled: false
83
+
84
+ RSpec/MultipleMemoizedHelpers:
85
+ Enabled: false
86
+
87
+ RSpec/HookArgument:
88
+ EnforcedStyle: each
89
+
90
+ RSpec/LeakyConstantDeclaration:
91
+ Enabled: false
92
+
93
+ RSpec/DescribeClass:
94
+ Enabled: false
95
+
96
+ RSpec/NestedGroups:
97
+ Enabled: false
98
+
99
+ RSpec/SpecFilePathFormat:
100
+ Enabled: false
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Flipp
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # avro-gen-ruby
2
+
3
+ Generate Ruby schema classes / models from Avro schemas.
4
+
5
+ `avro-gen-ruby` (namespace `AvroGen`) takes a directory of Avro `.avsc` schema files
6
+ and generates plain-Ruby classes for each record and enum, giving you typed,
7
+ IDE-friendly objects to work with instead of raw hashes. It was extracted from
8
+ [deimos-ruby](https://github.com/flipp-oss/deimos), which now depends on it.
9
+
10
+ ## Installation
11
+
12
+ ```ruby
13
+ gem 'avro-gen-ruby'
14
+ ```
15
+
16
+ ## Configuration
17
+
18
+ ```ruby
19
+ AvroGen.configure do |config|
20
+ config.schema_path = 'avro/schemas'
21
+ config.generated_class_path = 'app/lib/schema_classes'
22
+ config.nest_child_schemas = true
23
+ config.use_full_namespace = false
24
+ config.schema_namespace_map = {}
25
+ config.root_module = 'Schemas'
26
+ end
27
+ ```
28
+
29
+ | Setting | Default | Description |
30
+ |---------|---------|-------------|
31
+ | `schema_path` | `nil` | Local path to the directory containing your Avro `.avsc` schema files. Required for generation. |
32
+ | `generated_class_path` | `app/lib/schema_classes` | Local path that generated schema classes are written to. |
33
+ | `nest_child_schemas` | `true` | When `true`, subschemas (nested records/enums) are nested inside the generated class for the parent schema. When `false`, each subschema is generated as its own file. |
34
+ | `use_full_namespace` | `false` | When `true`, generate nested folders/modules matching the full Avro namespace (e.g. `com.my-org.Foo` → `Schemas::Com::MyOrg::Foo`). When `false`, all classes are generated directly under the root module. |
35
+ | `schema_namespace_map` | `{}` | A map of namespace prefixes to base module name(s), used to reduce nesting when `use_full_namespace` is `true`. Example: `{ 'com.mycompany.suborg' => ['SchemaClasses'] }` generates classes under `SchemaClasses::` instead of `Schemas::Com::Mycompany::Suborg::`. Has no effect unless `use_full_namespace` is `true`. |
36
+ | `root_module` | `'Schemas'` | The top-level module that generated classes are nested under. |
37
+
38
+ ## Usage
39
+
40
+ Generate classes for every schema in `schema_path`:
41
+
42
+ ```bash
43
+ rake avro:generate
44
+ ```
45
+
46
+ Generated classes inherit from `AvroGen::SchemaClass::Record` / `AvroGen::SchemaClass::Enum`
47
+ and are namespaced under the configured `root_module` (default `Schemas`).
48
+
49
+ ### Migrating from Deimos
50
+
51
+ If you previously generated classes with Deimos, they reference `Deimos::SchemaClass::*`.
52
+ Those still load (Deimos maps them to the AvroGen equivalents with a deprecation warning),
53
+ but you can rewrite them in place:
54
+
55
+ ```bash
56
+ rake avro:upgrade
57
+ ```
58
+
59
+ ## License
60
+
61
+ MIT
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ begin
5
+ require 'rspec/core/rake_task'
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+ task(default: :spec)
9
+ rescue LoadError
10
+ # no rspec available
11
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'avro_gen/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'avro-gen-ruby'
9
+ spec.version = AvroGen::VERSION
10
+ spec.authors = ['Daniel Orner']
11
+ spec.email = ['daniel.orner@flipp.com']
12
+ spec.summary = 'Generate Ruby schema classes from Avro schemas.'
13
+ spec.homepage = 'https://github.com/flipp-oss/avro-gen-ruby'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
17
+ spec.require_paths = ['lib']
18
+ spec.required_ruby_version = '>= 3.2'
19
+
20
+ spec.add_dependency('activesupport', '>= 6.0')
21
+ spec.add_dependency('avro', '~> 1.9')
22
+ spec.add_dependency('railties', '>= 6.0')
23
+ spec.add_dependency('schema_registry_client')
24
+
25
+ spec.add_development_dependency('rake', '~> 13')
26
+ spec.add_development_dependency('rspec', '~> 3')
27
+ spec.add_development_dependency('rspec-snapshot', '~> 2.0')
28
+ spec.add_development_dependency('rubocop', '~> 1.0')
29
+ spec.add_development_dependency('rubocop-rspec', '~> 3.0')
30
+
31
+ spec.metadata['rubygems_mfa_required'] = 'true'
32
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'avro'
4
+ require 'active_support/core_ext/string'
5
+
6
+ module AvroGen
7
+ # Helper methods for interpreting Avro schema objects when generating classes.
8
+ module AvroParser
9
+ class << self
10
+ # @param schema [Avro::Schema::NamedSchema] A named schema
11
+ # @return [String]
12
+ def schema_classname(schema)
13
+ schema.name.underscore.camelize.singularize
14
+ end
15
+
16
+ # Converts Avro::Schema::NamedSchema's to String form for generated YARD docs.
17
+ # Recursively handles the typing for Arrays, Maps and Unions.
18
+ # @param avro_schema [Avro::Schema::NamedSchema]
19
+ # @return [String] A string representation of the Type of this SchemaField
20
+ def field_type(avro_schema)
21
+ case avro_schema.type_sym
22
+ when :string, :boolean
23
+ avro_schema.type_sym.to_s.titleize
24
+ when :int, :long
25
+ 'Integer'
26
+ when :float, :double
27
+ 'Float'
28
+ when :record, :enum
29
+ schema_classname(avro_schema)
30
+ when :array
31
+ arr_t = field_type(AvroGen::SchemaField.new('n/a', avro_schema.items).type)
32
+ "Array<#{arr_t}>"
33
+ when :map
34
+ map_t = field_type(AvroGen::SchemaField.new('n/a', avro_schema.values).type)
35
+ "Hash<String, #{map_t}>"
36
+ when :union
37
+ types = avro_schema.schemas.map do |t|
38
+ field_type(AvroGen::SchemaField.new('n/a', t).type)
39
+ end
40
+ types.join(', ')
41
+ when :null
42
+ 'nil'
43
+ end
44
+ end
45
+
46
+ # Returns the base type of this schema. Decodes Arrays, Maps and Unions
47
+ # @param schema [Avro::Schema::NamedSchema]
48
+ # @return [Avro::Schema::NamedSchema]
49
+ def schema_base_class(schema)
50
+ case schema.type_sym
51
+ when :array
52
+ schema_base_class(schema.items)
53
+ when :map
54
+ schema_base_class(schema.values)
55
+ when :union
56
+ schema.schemas.map(&method(:schema_base_class)).
57
+ reject { |s| s.type_sym == :null }.first
58
+ else
59
+ schema
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AvroGen
4
+ # Configuration for schema class generation.
5
+ class Configuration
6
+ # Local path to look for Avro schemas (.avsc files) in.
7
+ # @return [String]
8
+ attr_accessor :schema_path
9
+
10
+ # Local path for schema classes to be generated in.
11
+ # @return [String]
12
+ attr_accessor :generated_class_path
13
+
14
+ # Set to false to generate child schemas as their own files.
15
+ # @return [Boolean]
16
+ attr_accessor :nest_child_schemas
17
+
18
+ # Set to true to generate folders matching the last part of the schema namespace.
19
+ # @return [Boolean]
20
+ attr_accessor :use_full_namespace
21
+
22
+ # Use this option to reduce nesting when using use_full_namespace.
23
+ # For example: { 'com.mycompany.suborg' => 'SchemaClasses' }
24
+ # would replace a prefix matching the given key with the module name SchemaClasses.
25
+ # @return [Hash]
26
+ attr_accessor :schema_namespace_map
27
+
28
+ # The top-level module that generated classes are nested under.
29
+ # @return [String]
30
+ attr_accessor :root_module
31
+
32
+ def initialize
33
+ reset!
34
+ end
35
+
36
+ # Restore all settings to their defaults.
37
+ # @return [void]
38
+ def reset!
39
+ @schema_path = nil
40
+ @generated_class_path = 'app/lib/schema_classes'
41
+ @nest_child_schemas = true
42
+ @use_full_namespace = false
43
+ @schema_namespace_map = {}
44
+ @root_module = 'Schemas'
45
+ end
46
+ end
47
+
48
+ class << self
49
+ # @return [AvroGen::Configuration]
50
+ def config
51
+ @config ||= Configuration.new
52
+ end
53
+
54
+ # @yieldparam [AvroGen::Configuration]
55
+ # @return [void]
56
+ def configure
57
+ yield config if block_given?
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AvroGen
4
+ # Raised when a subclass fails to implement a required method.
5
+ class MissingImplementationError < StandardError; end
6
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is autogenerated by AvroGen, Do NOT modify
4
+ <%= @modules.map { |m| "module #{m}"}.join('; ') %>
5
+ ### Primary Schema Class ###
6
+ <%=- @main_class_definition -%>
7
+
8
+ <%= @modules.map { "end" }.join('; ') %>
@@ -0,0 +1,13 @@
1
+ # Autogenerated Schema for Enum at <%= @current_schema.namespace %>.<%= @current_schema.name %>
2
+ class <%= AvroGen::AvroParser.schema_classname(@current_schema) %> < AvroGen::SchemaClass::Enum
3
+ # @override
4
+ def symbols
5
+ %w(<%= @current_schema.symbols.join(' ') %>)
6
+ end
7
+
8
+ <% @current_schema.symbols.each do |symbol| %>
9
+ def <%= symbol.underscore %>?
10
+ @value == '<%= symbol %>'
11
+ end
12
+ <% end %>
13
+ end
@@ -0,0 +1,102 @@
1
+ # Autogenerated Schema for Record at <%= @current_schema.namespace %>.<%= @current_schema.name %>
2
+ class <%= AvroGen::AvroParser.schema_classname(@current_schema) %> < AvroGen::SchemaClass::Record
3
+ <% if @sub_schema_templates.present? -%>
4
+
5
+ ### Secondary Schema Classes ###
6
+ <%- @sub_schema_templates.each do |schema_template| -%>
7
+ <%=- schema_template.gsub(/^/, " ") %>
8
+
9
+ <%- end -%>
10
+ <% end -%>
11
+
12
+ <%- if @field_assignments.select{ |h| h[:is_schema_class] }.any? -%>
13
+ ### Attribute Readers ###
14
+ <%- @field_assignments.select{ |h| h[:is_schema_class] }.each do |method_definition| -%>
15
+ # @return [<%= method_definition[:deimos_type] %>]
16
+ attr_reader :<%= method_definition[:field].name %>
17
+ <%- end -%>
18
+
19
+ <% end -%>
20
+ <%- if @field_assignments.select{ |h| !h[:is_schema_class] }.any? -%>
21
+ ### Attribute Accessors ###
22
+ <%- @field_assignments.select{ |h| !h[:is_schema_class] }.each do |method_definition| -%>
23
+ # @return [<%= method_definition[:deimos_type] %>]
24
+ attr_accessor :<%= method_definition[:field].name %>
25
+ <%- end -%>
26
+
27
+ <% end -%>
28
+ <%- if @field_assignments.select{ |h| h[:is_schema_class] }.any? -%>
29
+ ### Attribute Writers ###
30
+ <%- @field_assignments.select{ |h| h[:is_schema_class] }.each do |method_definition| -%>
31
+ # @return [<%= method_definition[:deimos_type] %>]
32
+ def <%= method_definition[:field].name %>=(<%= method_definition[:method_argument] %>)
33
+ <%- if method_definition[:field_type] == :array -%>
34
+ @<%= method_definition[:field].name %> = values&.map do |value|
35
+ <%= method_definition[:field_initialization] %>
36
+ end
37
+ <%- elsif method_definition[:field_type] == :map -%>
38
+ @<%= method_definition[:field].name %> = values&.transform_values do |value|
39
+ <%= method_definition[:field_initialization] %>
40
+ end
41
+ <%- else -%>
42
+ @<%= method_definition[:field].name %> = <%= method_definition[:field_initialization] %>
43
+ <%- end -%>
44
+ end
45
+
46
+ <%- end -%>
47
+ <% end -%>
48
+ <%- if @field_assignments.select{ |h| h[:is_complex_union] }.any? -%>
49
+ <%- @field_assignments.select{ |h| h[:is_complex_union] }.each do |method_definition| -%>
50
+ # Helper method to determine which schema type to use for <%= method_definition[:field].name %>
51
+ # @param value [Hash, nil]
52
+ # @param from_message [Boolean] whether this was initialized from a real Avro message
53
+ # @return [Object, nil]
54
+ def initialize_<%= method_definition[:field].name %>_type(value, from_message: false)
55
+ return nil if value.nil?
56
+
57
+ klass = [<%= method_definition[:field].type.schemas.reject { |s| s.type_sym == :null }.select { |s| s.type_sym == :record }.map { |s| AvroGen::AvroParser.schema_classname(s) }.join(', ') %>].find do |candidate|
58
+ fields = candidate.new.as_json.keys
59
+ (value.keys - fields).empty?
60
+ end
61
+
62
+ klass.initialize_from_value(value, from_message: self._from_message)
63
+ end
64
+
65
+ <%- end -%>
66
+ <% end -%>
67
+ # @override
68
+ <%= @initialization_definition %>
69
+ @_from_message = _from_message
70
+ super
71
+ <%- @fields.each do |field| -%>
72
+ self.<%= field.name %> = <%= field.name %>
73
+ <% end -%>
74
+ end
75
+
76
+ # @override
77
+ def schema
78
+ '<%= @current_schema.name %>'
79
+ end
80
+
81
+ # @override
82
+ def namespace
83
+ '<%= @current_schema.namespace %>'
84
+ end
85
+ <%- if @tombstone_assignment %>
86
+ def self.tombstone(key)
87
+ record = self.allocate
88
+ <%- if @tombstone_assignment.present? -%>
89
+ <%= @tombstone_assignment %>
90
+ <%- end -%>
91
+ record
92
+ end
93
+ <%- end %>
94
+ # @override
95
+ def as_json(_opts={})
96
+ {
97
+ <%- @fields.each do |field| -%>
98
+ <%= field_as_json(field) %>
99
+ <% end -%>
100
+ }
101
+ end
102
+ end