From 3b0d7c325e6ca9d62b0d07eaf77aafaae1b76b0e Mon Sep 17 00:00:00 2001
From: Anton Sattarov <dirty.mew@gmail.com>
Date: Thu, 5 Dec 2024 00:41:14 +0100
Subject: [PATCH] add encoder and change server template

---
 assets/templates/transport/grpc_client.tmpl  | 36 +-------
 assets/templates/transport/grpc_encoder.tmpl | 28 ++++++
 assets/templates/transport/grpc_server.tmpl  | 11 +--
 perxis-proto                                 |  2 +-
 pkg/invitations/client.go                    | 35 +++-----
 pkg/invitations/conv/proto_decoder.go        | 54 -----------
 pkg/invitations/encoder.go                   | 35 ++++++++
 pkg/invitations/encoder/grpc.go              | 94 ++++++++++++++++++++
 pkg/invitations/server.go                    | 31 +++----
 9 files changed, 194 insertions(+), 132 deletions(-)
 create mode 100644 assets/templates/transport/grpc_encoder.tmpl
 delete mode 100644 pkg/invitations/conv/proto_decoder.go
 create mode 100644 pkg/invitations/encoder.go
 create mode 100644 pkg/invitations/encoder/grpc.go

diff --git a/assets/templates/transport/grpc_client.tmpl b/assets/templates/transport/grpc_client.tmpl
index 757071cf..7e11e72a 100644
--- a/assets/templates/transport/grpc_client.tmpl
+++ b/assets/templates/transport/grpc_client.tmpl
@@ -10,46 +10,18 @@ import (
 
 type Client struct {
     client  pb.{{.Interface.Name}}Client
-    decoder ProtoDecoder
+    decoder ProtoEncoder
 }
 
 var _ {{.Interface.Name}} = &Client{}
 
-func NewClient(conn *grpc.ClientConn, decoder ProtoDecoder) *Client {
+func NewClient(conn *grpc.ClientConn, decoder ProtoEncoder) *Client {
     return &Client{
     client:  pb.New{{.Interface.Name}}Client(conn),
     decoder: decoder,
     }
 }
 
-type ProtoDecoder interface {
-{{range $method := .Interface.Methods}}
-{{- if $method.ReturnsError}}
-    {{ $resList := list }}
-    {{ $resListLen := add 0 }}
-    {{- range $param := $method.Results -}}
-            {{- if not ( and $method.ReturnsError (eq $param.Name "err")) -}}
-            {{- $resList = append $resList (printf "%s %s" $param.Name $param.Type) -}}
-            {{- $resListLen = add $resListLen 1 -}}
-         {{- end -}}
-    {{- end -}}
-
-    {{- $paramList := list -}}
-        {{- range $param := $method.Params -}}
-        {{- if not ( and $method.AcceptsContext (eq $param.Name "ctx")) -}}
-            {{- $paramList = append $paramList (printf "%s %s" $param.Name $param.Type)
-              -}}
-        {{- end -}}
-    {{- end -}}
-
-    {{ $method.Name }}Request({{ $paramList | join `, ` }}) *pb.{{ $method.Name }}Request
-    {{- if gt $resListLen 0 }}
-    {{ $method.Name }}Response(res *pb.{{ $method.Name }}Response) ({{ $resList | join `, ` }})
-    {{- end }}
-{{- end -}}
-{{end}}
-}
-
 
 {{range $method := .Interface.Methods}}
     {{- if $method.ReturnsError}}
@@ -72,14 +44,14 @@ type ProtoDecoder interface {
 
     // {{$method.Name}} implements {{$.Interface.Name}}
     func (c *Client) {{$method.Declaration}} {
-        request := c.decoder.{{$method.Name}}Request({{ $paramList | join `, ` }})
+        request := c.decoder.Encode{{$method.Name}}Request({{ $paramList | join `, ` }})
         {{- if gt $resListLen 0 }}
             res, err := c.client.{{ $method.Name }}(ctx, request)
         {{- else }}
             _, err = c.client.{{ $method.Name }}(ctx, request)
         {{- end }}
         {{- if gt $resListLen 0 }}
-            {{ $resList | join `,` }} = c.decoder.{{ $method.Name }}Response(res)
+            {{ $resList | join `,` }} = c.decoder.Encode{{ $method.Name }}Response(res)
         {{- end }}
         return
         }
diff --git a/assets/templates/transport/grpc_encoder.tmpl b/assets/templates/transport/grpc_encoder.tmpl
new file mode 100644
index 00000000..f1e684ef
--- /dev/null
+++ b/assets/templates/transport/grpc_encoder.tmpl
@@ -0,0 +1,28 @@
+type ProtoEncoder interface {
+{{range $method := .Interface.Methods}}
+    {{- if $method.ReturnsError}}
+        {{ $resList := list }}
+        {{ $resListLen := add 0 }}
+        {{- range $param := $method.Results -}}
+            {{- if not ( and $method.ReturnsError (eq $param.Name "err")) -}}
+            {{- $resList = append $resList (printf "%s %s" $param.Name $param.Type) -}}
+            {{- $resListLen = add $resListLen 1 -}}
+            {{- end -}}
+        {{- end -}}
+
+    {{- $paramList := list -}}
+    {{- range $param := $method.Params -}}
+        {{- if not ( and $method.AcceptsContext (eq $param.Name "ctx")) -}}
+        {{- $paramList = append $paramList (printf "%s %s" $param.Name $param.Type) -}}
+        {{- end -}}
+    {{- end -}}
+
+        Encode{{ $method.Name }}Request({{ $paramList | join `, ` }}) *pb.{{ $method.Name }}Request
+        Decode{{ $method.Name }}Request(request *pb.{{ $method.Name }}Request) ({{ $paramList | join `, ` }})
+    {{- if gt $resListLen 0 }}
+        Encode{{ $method.Name }}Response(response *pb.{{ $method.Name }}Response) ({{ $resList | join `, ` }})
+        Decode{{ $method.Name }}Response({{ $resList | join `, ` }}) *pb.{{ $method.Name }}Response
+    {{- end }}
+    {{- end -}}
+{{end}}
+}
\ No newline at end of file
diff --git a/assets/templates/transport/grpc_server.tmpl b/assets/templates/transport/grpc_server.tmpl
index 1d3aad0b..e2f22458 100644
--- a/assets/templates/transport/grpc_server.tmpl
+++ b/assets/templates/transport/grpc_server.tmpl
@@ -8,10 +8,11 @@ import (
 type Server struct {
 	pb.Unimplemented{{.Interface.Name}}Server
 	service {{.Interface.Name}}
+    encoder ProtoEncoder
 }
 
-func NewServer(svc {{.Interface.Name}}) *Server {
-	return &Server{service: svc}
+func NewServer(svc {{.Interface.Name}}, encoder ProtoEncoder) *Server {
+	return &Server{service: svc, encoder: encoder}
 }
 
 func RegisterServer(grpcSrv *grpc.Server, srv *Server) {
@@ -38,21 +39,21 @@ func RegisterServer(grpcSrv *grpc.Server, srv *Server) {
   {{- $paramList := list -}}
     {{- range $param := $method.Params -}}
         {{- if not ( and $method.AcceptsContext (eq $param.Name "ctx")) -}}
-            {{- $paramList = append $paramList (printf "req.%s" $param.Name ) -}}
+            {{- $paramList = append $paramList $param.Name -}}
         {{- end -}}
   {{- end -}}
 
 
 // {{$method.Name}} implements {{$.Interface.Name}}
   func (s *Server) {{$method.Name}}(ctx context.Context, request *pb.{{$method.Name}}Request) (response {{ $response }}, err error) {
-    req := {{$method.Name}}RequestFromPB(request)
+    {{ $paramList | join `,` }} := s.encoder.Decode{{$method.Name}}Request(request)
     {{- if gt $resListLen 0 }}
         {{ $method.ResultsNames | join `,` }} := s.service.{{ $method.Name }}(ctx, {{ $paramList | join `, ` }})
     {{- else }}
         err = s.service.{{ $method.Name }}(ctx, {{ $paramList | join `, ` }})
     {{- end }}
     {{- if gt $resListLen 0 }}
-        response = {{ $method.Name }}ResponseToPB({{ $resList | join `,` }})
+        response = s.encoder.Decode{{ $method.Name }}Response({{ $resList | join `,` }})
     {{- end }}
     return
   }
diff --git a/perxis-proto b/perxis-proto
index 9b500f82..28531974 160000
--- a/perxis-proto
+++ b/perxis-proto
@@ -1 +1 @@
-Subproject commit 9b500f82cbfed60c8aaee6ca3e1004df072368bc
+Subproject commit 28531974cc43f8ce31e7456241f3cb2535f8c179
diff --git a/pkg/invitations/client.go b/pkg/invitations/client.go
index 6566d65d..55e469f9 100644
--- a/pkg/invitations/client.go
+++ b/pkg/invitations/client.go
@@ -16,67 +16,52 @@ import (
 
 type Client struct {
 	client  pb.InvitationsClient
-	decoder ProtoDecoder
+	decoder ProtoEncoder
 }
 
 var _ Invitations = &Client{}
 
-func NewClient(conn *grpc.ClientConn, decoder ProtoDecoder) *Client {
+func NewClient(conn *grpc.ClientConn, decoder ProtoEncoder) *Client {
 	return &Client{
 		client:  pb.NewInvitationsClient(conn),
 		decoder: decoder,
 	}
 }
 
-type ProtoDecoder interface {
-	AcceptRequest(invitationId string, userId string) *pb.AcceptRequest
-
-	CreateRequest(invitation *Invitation) *pb.CreateRequest
-	CreateResponse(res *pb.CreateResponse) (created *Invitation)
-
-	DeleteRequest(invitationId string) *pb.DeleteRequest
-
-	FindRequest(filter *Filter, opts *options.FindOptions) *pb.FindRequest
-	FindResponse(res *pb.FindResponse) (invitations []*Invitation, total int)
-
-	GetRequest(invitationId string) *pb.GetRequest
-	GetResponse(res *pb.GetResponse) (invitation *Invitation)
-}
-
 // Accept implements Invitations
 func (c *Client) Accept(ctx context.Context, invitationId string, userId string) (err error) {
-	request := c.decoder.AcceptRequest(invitationId, userId)
+	request := c.decoder.EncodeAcceptRequest(invitationId, userId)
 	_, err = c.client.Accept(ctx, request)
 	return
 }
 
 // Create implements Invitations
 func (c *Client) Create(ctx context.Context, invitation *Invitation) (created *Invitation, err error) {
-	request := c.decoder.CreateRequest(invitation)
+	request := c.decoder.EncodeCreateRequest(invitation)
 	res, err := c.client.Create(ctx, request)
-	created = c.decoder.CreateResponse(res)
+	created = c.decoder.EncodeCreateResponse(res)
 	return
 }
 
 // Delete implements Invitations
 func (c *Client) Delete(ctx context.Context, invitationId string) (err error) {
-	request := c.decoder.DeleteRequest(invitationId)
+	request := c.decoder.EncodeDeleteRequest(invitationId)
 	_, err = c.client.Delete(ctx, request)
 	return
 }
 
 // Find implements Invitations
 func (c *Client) Find(ctx context.Context, filter *Filter, opts *options.FindOptions) (invitations []*Invitation, total int, err error) {
-	request := c.decoder.FindRequest(filter, opts)
+	request := c.decoder.EncodeFindRequest(filter, opts)
 	res, err := c.client.Find(ctx, request)
-	invitations, total = c.decoder.FindResponse(res)
+	invitations, total = c.decoder.EncodeFindResponse(res)
 	return
 }
 
 // Get implements Invitations
 func (c *Client) Get(ctx context.Context, invitationId string) (invitation *Invitation, err error) {
-	request := c.decoder.GetRequest(invitationId)
+	request := c.decoder.EncodeGetRequest(invitationId)
 	res, err := c.client.Get(ctx, request)
-	invitation = c.decoder.GetResponse(res)
+	invitation = c.decoder.EncodeGetResponse(res)
 	return
 }
diff --git a/pkg/invitations/conv/proto_decoder.go b/pkg/invitations/conv/proto_decoder.go
deleted file mode 100644
index 57c1c378..00000000
--- a/pkg/invitations/conv/proto_decoder.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package conv
-
-import (
-	"git.perx.ru/perxis/perxis-go/pkg/invitations"
-	"git.perx.ru/perxis/perxis-go/pkg/options"
-	pb "git.perx.ru/perxis/perxis-go/proto/invitations"
-)
-
-type Decoder struct {
-}
-
-var _ invitations.ProtoDecoder = &Decoder{}
-
-func (d Decoder) AcceptRequest(invitationId string, userId string) *pb.AcceptRequest {
-	return &pb.AcceptRequest{
-		InvitationId: invitationId,
-		UserId:       userId,
-	}
-}
-
-func (d Decoder) CreateRequest(invitation *invitations.Invitation) *pb.CreateRequest {
-	// TODO implement me
-	panic("implement me")
-}
-
-func (d Decoder) CreateResponse(res *pb.CreateResponse) (created *invitations.Invitation) {
-	// TODO implement me
-	panic("implement me")
-}
-
-func (d Decoder) DeleteRequest(invitationId string) *pb.DeleteRequest {
-	// TODO implement me
-	panic("implement me")
-}
-
-func (d Decoder) FindRequest(filter *invitations.Filter, opts *options.FindOptions) *pb.FindRequest {
-	// TODO implement me
-	panic("implement me")
-}
-
-func (d Decoder) FindResponse(res *pb.FindResponse) (invitations []*invitations.Invitation, total int) {
-	// TODO implement me
-	panic("implement me")
-}
-
-func (d Decoder) GetRequest(invitationId string) *pb.GetRequest {
-	// TODO implement me
-	panic("implement me")
-}
-
-func (d Decoder) GetResponse(res *pb.GetResponse) (invitation *invitations.Invitation) {
-	// TODO implement me
-	panic("implement me")
-}
diff --git a/pkg/invitations/encoder.go b/pkg/invitations/encoder.go
new file mode 100644
index 00000000..ddbcb5fb
--- /dev/null
+++ b/pkg/invitations/encoder.go
@@ -0,0 +1,35 @@
+// Code generated by gowrap. DO NOT EDIT.
+// template: ../../assets/templates/transport/grpc_encoder.tmpl
+// gowrap: http://github.com/hexdigest/gowrap
+
+package invitations
+
+import (
+	"git.perx.ru/perxis/perxis-go/pkg/options"
+	pb "git.perx.ru/perxis/perxis-go/proto/invitations"
+)
+
+//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/invitations -i Invitations -t ../../assets/templates/transport/grpc_encoder.tmpl -o encoder.go -l ""
+
+type ProtoEncoder interface {
+	EncodeAcceptRequest(invitationId string, userId string) *pb.AcceptRequest
+	DecodeAcceptRequest(request *pb.AcceptRequest) (invitationId string, userId string)
+
+	EncodeCreateRequest(invitation *Invitation) *pb.CreateRequest
+	DecodeCreateRequest(request *pb.CreateRequest) (invitation *Invitation)
+	EncodeCreateResponse(response *pb.CreateResponse) (created *Invitation)
+	DecodeCreateResponse(created *Invitation) *pb.CreateResponse
+
+	EncodeDeleteRequest(invitationId string) *pb.DeleteRequest
+	DecodeDeleteRequest(request *pb.DeleteRequest) (invitationId string)
+
+	EncodeFindRequest(filter *Filter, opts *options.FindOptions) *pb.FindRequest
+	DecodeFindRequest(request *pb.FindRequest) (filter *Filter, opts *options.FindOptions)
+	EncodeFindResponse(response *pb.FindResponse) (invitations []*Invitation, total int)
+	DecodeFindResponse(invitations []*Invitation, total int) *pb.FindResponse
+
+	EncodeGetRequest(invitationId string) *pb.GetRequest
+	DecodeGetRequest(request *pb.GetRequest) (invitationId string)
+	EncodeGetResponse(response *pb.GetResponse) (invitation *Invitation)
+	DecodeGetResponse(invitation *Invitation) *pb.GetResponse
+}
diff --git a/pkg/invitations/encoder/grpc.go b/pkg/invitations/encoder/grpc.go
new file mode 100644
index 00000000..a4488c09
--- /dev/null
+++ b/pkg/invitations/encoder/grpc.go
@@ -0,0 +1,94 @@
+package conv
+
+import (
+	"git.perx.ru/perxis/perxis-go/pkg/invitations"
+	"git.perx.ru/perxis/perxis-go/pkg/options"
+	pb "git.perx.ru/perxis/perxis-go/proto/invitations"
+)
+
+type Encoder struct {
+}
+
+var _ invitations.ProtoEncoder = &Encoder{}
+
+func (d Encoder) EncodeAcceptRequest(invitationId string, userId string) *pb.AcceptRequest {
+	return &pb.AcceptRequest{
+		InvitationId: invitationId,
+		UserId:       userId,
+	}
+}
+
+func (d Encoder) DecodeAcceptRequest(request *pb.AcceptRequest) (invitationId string, userId string) {
+	// TODO implement me
+	panic("implement me")
+}
+
+func (d Encoder) EncodeCreateRequest(invitation *invitations.Invitation) *pb.CreateRequest {
+	// TODO implement me
+	panic("implement me")
+}
+
+func (d Encoder) DecodeCreateRequest(request *pb.CreateRequest) (invitation *invitations.Invitation) {
+	// TODO implement me
+	panic("implement me")
+}
+
+func (d Encoder) EncodeCreateResponse(response *pb.CreateResponse) (created *invitations.Invitation) {
+	// TODO implement me
+	panic("implement me")
+}
+
+func (d Encoder) DecodeCreateResponse(created *invitations.Invitation) *pb.CreateResponse {
+	// TODO implement me
+	panic("implement me")
+}
+
+func (d Encoder) EncodeDeleteRequest(invitationId string) *pb.DeleteRequest {
+	// TODO implement me
+	panic("implement me")
+}
+
+func (d Encoder) DecodeDeleteRequest(request *pb.DeleteRequest) (invitationId string) {
+	// TODO implement me
+	panic("implement me")
+}
+
+func (d Encoder) EncodeFindRequest(filter *invitations.Filter, opts *options.FindOptions) *pb.FindRequest {
+	// TODO implement me
+	panic("implement me")
+}
+
+func (d Encoder) DecodeFindRequest(request *pb.FindRequest) (filter *invitations.Filter, opts *options.FindOptions) {
+	// TODO implement me
+	panic("implement me")
+}
+
+func (d Encoder) EncodeFindResponse(response *pb.FindResponse) (invitations []*invitations.Invitation, total int) {
+	// TODO implement me
+	panic("implement me")
+}
+
+func (d Encoder) DecodeFindResponse(invitations []*invitations.Invitation, total int) *pb.FindResponse {
+	// TODO implement me
+	panic("implement me")
+}
+
+func (d Encoder) EncodeGetRequest(invitationId string) *pb.GetRequest {
+	// TODO implement me
+	panic("implement me")
+}
+
+func (d Encoder) DecodeGetRequest(request *pb.GetRequest) (invitationId string) {
+	// TODO implement me
+	panic("implement me")
+}
+
+func (d Encoder) EncodeGetResponse(response *pb.GetResponse) (invitation *invitations.Invitation) {
+	// TODO implement me
+	panic("implement me")
+}
+
+func (d Encoder) DecodeGetResponse(invitation *invitations.Invitation) *pb.GetResponse {
+	// TODO implement me
+	panic("implement me")
+}
diff --git a/pkg/invitations/server.go b/pkg/invitations/server.go
index 8c220b75..74a394ed 100644
--- a/pkg/invitations/server.go
+++ b/pkg/invitations/server.go
@@ -17,10 +17,11 @@ import (
 type Server struct {
 	pb.UnimplementedInvitationsServer
 	service Invitations
+	encoder ProtoEncoder
 }
 
-func NewServer(svc Invitations) *Server {
-	return &Server{service: svc}
+func NewServer(svc Invitations, encoder ProtoEncoder) *Server {
+	return &Server{service: svc, encoder: encoder}
 }
 
 func RegisterServer(grpcSrv *grpc.Server, srv *Server) {
@@ -29,38 +30,38 @@ func RegisterServer(grpcSrv *grpc.Server, srv *Server) {
 
 // Accept implements Invitations
 func (s *Server) Accept(ctx context.Context, request *pb.AcceptRequest) (response *emptypb.Empty, err error) {
-	req := AcceptRequestFromPB(request)
-	err = s.service.Accept(ctx, req.invitationId, req.userId)
+	invitationId, userId := s.encoder.DecodeAcceptRequest(request)
+	err = s.service.Accept(ctx, invitationId, userId)
 	return
 }
 
 // Create implements Invitations
 func (s *Server) Create(ctx context.Context, request *pb.CreateRequest) (response *pb.CreateResponse, err error) {
-	req := CreateRequestFromPB(request)
-	created, err := s.service.Create(ctx, req.invitation)
-	response = CreateResponseToPB(created)
+	invitation := s.encoder.DecodeCreateRequest(request)
+	created, err := s.service.Create(ctx, invitation)
+	response = s.encoder.DecodeCreateResponse(created)
 	return
 }
 
 // Delete implements Invitations
 func (s *Server) Delete(ctx context.Context, request *pb.DeleteRequest) (response *emptypb.Empty, err error) {
-	req := DeleteRequestFromPB(request)
-	err = s.service.Delete(ctx, req.invitationId)
+	invitationId := s.encoder.DecodeDeleteRequest(request)
+	err = s.service.Delete(ctx, invitationId)
 	return
 }
 
 // Find implements Invitations
 func (s *Server) Find(ctx context.Context, request *pb.FindRequest) (response *pb.FindResponse, err error) {
-	req := FindRequestFromPB(request)
-	invitations, total, err := s.service.Find(ctx, req.filter, req.opts)
-	response = FindResponseToPB(invitations, total)
+	filter, opts := s.encoder.DecodeFindRequest(request)
+	invitations, total, err := s.service.Find(ctx, filter, opts)
+	response = s.encoder.DecodeFindResponse(invitations, total)
 	return
 }
 
 // Get implements Invitations
 func (s *Server) Get(ctx context.Context, request *pb.GetRequest) (response *pb.GetResponse, err error) {
-	req := GetRequestFromPB(request)
-	invitation, err := s.service.Get(ctx, req.invitationId)
-	response = GetResponseToPB(invitation)
+	invitationId := s.encoder.DecodeGetRequest(request)
+	invitation, err := s.service.Get(ctx, invitationId)
+	response = s.encoder.DecodeGetResponse(invitation)
 	return
 }
-- 
GitLab