diff --git a/CHANGELOG.md b/CHANGELOG.md index d59685c..c9fe784 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ## [Unreleased] - Add `skip-empty` option to prevent generating empty scaffolding for proto files without services - [#21](https://github.com/collectiveidea/protoc-gen-twirp_ruby/pull/21) -- Refactor code generator to improve internal readability - [#12](https://github.com/collectiveidea/protoc-gen-twirp_ruby/pull/12), [#13](https://github.com/collectiveidea/protoc-gen-twirp_ruby/pull/13) +- Refactor code generator to improve internal readability - [#12](https://github.com/collectiveidea/protoc-gen-twirp_ruby/pull/12), [#13](https://github.com/collectiveidea/protoc-gen-twirp_ruby/pull/13), [#22](https://github.com/collectiveidea/protoc-gen-twirp_ruby/pull/22) - Remove unnecessary extra files from packaged gem - [#11](https://github.com/collectiveidea/protoc-gen-twirp_ruby/pull/11) ## [1.0.0] - 2024-05-10 diff --git a/lib/twirp/protoc_plugin/code_generator.rb b/lib/twirp/protoc_plugin/code_generator.rb index 9ad1854..9725aee 100644 --- a/lib/twirp/protoc_plugin/code_generator.rb +++ b/lib/twirp/protoc_plugin/code_generator.rb @@ -3,6 +3,7 @@ require_relative "../../google/protobuf/compiler/plugin_pb" require_relative "../../core_ext/string/camel_case" require_relative "../../core_ext/string/snake_case" +require_relative "descriptor_ext/service_descriptor_proto_ext" require "stringio" module Twirp @@ -52,14 +53,7 @@ def generate output << "\n" if index > 0 service_name = service.name - # The generated service class name should end in "Service"; Only append the - # suffix if the service is not already well-named. - service_class_name = if service_name.end_with?("Service") - service_name - else - service_name + "Service" - end - service_class_name = service_class_name.camel_case + service_class_name = service.service_class_name # Generate service class output << line("class #{service_class_name} < ::Twirp::Service", indent_level) @@ -76,8 +70,7 @@ def generate # Generate client class - # Strip the "Service" suffix if present for better readability. - client_class_name = (service_name.delete_suffix("Service") + "Client").camel_case + client_class_name = service.client_class_name output << "\n" output << line("class #{client_class_name} < ::Twirp::Client", indent_level) diff --git a/lib/twirp/protoc_plugin/descriptor_ext/service_descriptor_proto_ext.rb b/lib/twirp/protoc_plugin/descriptor_ext/service_descriptor_proto_ext.rb new file mode 100644 index 0000000..a5d41f9 --- /dev/null +++ b/lib/twirp/protoc_plugin/descriptor_ext/service_descriptor_proto_ext.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require_relative "../../../core_ext/string/camel_case" + +class Google::Protobuf::ServiceDescriptorProto + def service_class_name + # The generated service class name should end in "Service"; A well-named + # service may already end with "Service" but we can't guarantee it. Use + # class_name_without_service_suffix to #avoid "ServiceService" + class_name_without_service_suffix + "Service" + end + + def client_class_name + class_name_without_service_suffix + "Client" + end + + private + + def class_name_without_service_suffix + name.delete_suffix("Service").camel_case + end +end diff --git a/spec/twirp/protoc_plugin/descriptor_ext/service_descriptor_proto_ext_spec.rb b/spec/twirp/protoc_plugin/descriptor_ext/service_descriptor_proto_ext_spec.rb new file mode 100644 index 0000000..75515ed --- /dev/null +++ b/spec/twirp/protoc_plugin/descriptor_ext/service_descriptor_proto_ext_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +RSpec.describe Google::Protobuf::ServiceDescriptorProto do + describe "#service_class_name" do + it "appends \"Service\" when the service is not well-named" do + service = Google::Protobuf::ServiceDescriptorProto.new(name: "HelloWorld") + expect(service.service_class_name).to eq("HelloWorldService") + end + + it "does not alter the service name when the service is well-named" do + service = Google::Protobuf::ServiceDescriptorProto.new(name: "HelloWorldService") + expect(service.service_class_name).to eq("HelloWorldService") + end + end + + describe "#client_class_name" do + it "appends \"Client\" when the service is not well-named" do + service = Google::Protobuf::ServiceDescriptorProto.new(name: "HelloWorld") + expect(service.client_class_name).to eq("HelloWorldClient") + end + + it "trims \"Service\" and appends \"Client\" when the service is well-named" do + service = Google::Protobuf::ServiceDescriptorProto.new(name: "HelloWorldService") + expect(service.client_class_name).to eq("HelloWorldClient") + end + end +end