feat: api
This commit is contained in:
commit
696184f41a
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.idea
|
||||||
|
go.sum
|
70
example.proto
Normal file
70
example.proto
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package controller;
|
||||||
|
|
||||||
|
option go_package = "./;core";
|
||||||
|
|
||||||
|
|
||||||
|
// @route_group: true
|
||||||
|
// @route_api: /api/file
|
||||||
|
// @gen_to: ./core/file_controller.go
|
||||||
|
service File {
|
||||||
|
// @desc: 列表
|
||||||
|
// @author: Young Xu
|
||||||
|
// @method: GET
|
||||||
|
// @api: /list
|
||||||
|
rpc List (ListReq) returns (ListResp);
|
||||||
|
// @desc: 上传
|
||||||
|
// @author: Young Xu
|
||||||
|
// @method: POST
|
||||||
|
// @api: /upload
|
||||||
|
rpc Upload (UploadReq) returns (UploadResp);
|
||||||
|
// @desc: 删除
|
||||||
|
// @author: Young Xu
|
||||||
|
// @method: POST
|
||||||
|
// @api: /delete
|
||||||
|
rpc Delete (DeleteReq) returns (DeleteResp);
|
||||||
|
// @desc: 下载
|
||||||
|
// @author: Young Xu
|
||||||
|
// @method: GET
|
||||||
|
// @api: /download
|
||||||
|
rpc Download (DownloadReq) returns (DownloadResp);
|
||||||
|
// @desc:
|
||||||
|
// @author:
|
||||||
|
// @method:
|
||||||
|
// @api: /update_user_info
|
||||||
|
rpc UpdateUserInfo (UpdateUserInfoReq) returns (UpdateUserInfoResp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message ListReq {}
|
||||||
|
|
||||||
|
message ListResp {
|
||||||
|
message Item {
|
||||||
|
string filename = 1; // 文件名
|
||||||
|
string file_size = 2; // 文件大小
|
||||||
|
string created_at = 3; // 上传时间
|
||||||
|
}
|
||||||
|
repeated Item items = 1; // 列表
|
||||||
|
}
|
||||||
|
|
||||||
|
message UploadReq {}
|
||||||
|
|
||||||
|
message UploadResp {}
|
||||||
|
|
||||||
|
message DeleteReq {
|
||||||
|
string filename = 1; // 文件名
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteResp {}
|
||||||
|
|
||||||
|
message DownloadReq {
|
||||||
|
// @v: required
|
||||||
|
string f = 1; // 文件地址
|
||||||
|
}
|
||||||
|
|
||||||
|
message DownloadResp {}
|
||||||
|
|
||||||
|
message UpdateUserInfoReq {}
|
||||||
|
|
||||||
|
message UpdateUserInfoResp {}
|
15
go.mod
Normal file
15
go.mod
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
module gitter.top/coco/gobuf
|
||||||
|
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/emicklei/proto v1.11.1
|
||||||
|
github.com/stretchr/testify v1.8.2
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
gitter.top/sync/proto-contrib v0.15.0
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
)
|
118
gobuf.go
Normal file
118
gobuf.go
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package gobuf
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"github.com/emicklei/proto"
|
||||||
|
"gitter.top/sync/proto-contrib/pkg/protofmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Parser struct {
|
||||||
|
filename string
|
||||||
|
rawData io.Reader
|
||||||
|
proto *proto.Proto
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewParser(file string) (*Parser, error) {
|
||||||
|
reader, err := os.Open(file)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer reader.Close()
|
||||||
|
|
||||||
|
parser := proto.NewParser(reader)
|
||||||
|
definition, err := parser.Parse()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Parser{
|
||||||
|
filename: file,
|
||||||
|
rawData: reader,
|
||||||
|
proto: definition,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (parser *Parser) ExistService(serviceName string) bool {
|
||||||
|
var result bool
|
||||||
|
proto.Walk(parser.proto, proto.WithService(func(service *proto.Service) {
|
||||||
|
if service.Name == serviceName {
|
||||||
|
result = true
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (parser *Parser) ExistMessage(messageName string) bool {
|
||||||
|
var result bool
|
||||||
|
proto.Walk(parser.proto, proto.WithMessage(func(message *proto.Message) {
|
||||||
|
if message.Name == messageName {
|
||||||
|
result = true
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (parser *Parser) ExistRPC(serviceName, rpcName string) bool {
|
||||||
|
var result bool
|
||||||
|
proto.Walk(parser.proto, proto.WithService(func(service *proto.Service) {
|
||||||
|
if service.Name != serviceName {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, element := range service.Elements {
|
||||||
|
if rpc, ok := element.(*proto.RPC); ok {
|
||||||
|
if rpc.Name == rpcName {
|
||||||
|
result = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (parser *Parser) AddRPC(serviceName, rpcName string) error {
|
||||||
|
proto.Walk(parser.proto, proto.WithService(func(service *proto.Service) {
|
||||||
|
if service.Name != serviceName {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
service.Elements = append(service.Elements, &proto.RPC{
|
||||||
|
Comment: &proto.Comment{
|
||||||
|
Lines: []string{
|
||||||
|
" @desc: ",
|
||||||
|
" @author: ",
|
||||||
|
" @method: ",
|
||||||
|
" @api: /" + calm2Case(rpcName),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Name: rpcName,
|
||||||
|
RequestType: rpcName + "Req",
|
||||||
|
ReturnsType: rpcName + "Resp",
|
||||||
|
Parent: service,
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
|
||||||
|
parser.proto.Elements = append(parser.proto.Elements, &proto.Message{
|
||||||
|
Name: rpcName + "Req",
|
||||||
|
Parent: parser.proto,
|
||||||
|
})
|
||||||
|
parser.proto.Elements = append(parser.proto.Elements, &proto.Message{
|
||||||
|
Name: rpcName + "Resp",
|
||||||
|
Parent: parser.proto,
|
||||||
|
})
|
||||||
|
|
||||||
|
return parser.writeSync()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (parser *Parser) writeSync() error {
|
||||||
|
var buf = new(bytes.Buffer)
|
||||||
|
|
||||||
|
protofmt.NewFormatter(buf, " ").Format(parser.proto) // 1 tab
|
||||||
|
|
||||||
|
// write back to input
|
||||||
|
if err := os.WriteFile(parser.filename, buf.Bytes(), os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
22
gobuf_test.go
Normal file
22
gobuf_test.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package gobuf
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParser_AddRPC(t *testing.T) {
|
||||||
|
parser, err := NewParser("example.proto")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
existService := parser.ExistService("File")
|
||||||
|
assert.EqualValues(t, true, existService)
|
||||||
|
existRPC := parser.ExistRPC("File", "List")
|
||||||
|
assert.EqualValues(t, true, existRPC)
|
||||||
|
existRPC = parser.ExistRPC("File", "List1")
|
||||||
|
assert.EqualValues(t, false, existRPC)
|
||||||
|
existMsg := parser.ExistMessage("DeleteReq")
|
||||||
|
assert.EqualValues(t, true, existMsg)
|
||||||
|
err = parser.AddRPC("File", "UpdateUserInfo")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
}
|
22
utils.go
Normal file
22
utils.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package gobuf
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"unicode"
|
||||||
|
)
|
||||||
|
|
||||||
|
// calm2Case 驼峰转下划线
|
||||||
|
func calm2Case(src string) string {
|
||||||
|
buffer := new(bytes.Buffer)
|
||||||
|
for i, r := range src {
|
||||||
|
if unicode.IsUpper(r) {
|
||||||
|
if i != 0 {
|
||||||
|
buffer.WriteRune('_')
|
||||||
|
}
|
||||||
|
buffer.WriteRune(unicode.ToLower(r))
|
||||||
|
} else {
|
||||||
|
buffer.WriteRune(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer.String()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user