diff --git a/Makefile b/Makefile index 07b4754..632b172 100644 --- a/Makefile +++ b/Makefile @@ -16,4 +16,6 @@ generate-code: -functionFile function.go \ -typeFile type.go \ -unmarshalerFile unmarshaler.go - go fmt ./client + +format-project: + go fmt ./... diff --git a/client/puller/chat.go b/client/puller/chat.go index f86c929..415adbd 100644 --- a/client/puller/chat.go +++ b/client/puller/chat.go @@ -1,52 +1,52 @@ package puller import ( - "github.com/zelenin/go-tdlib/client" + "github.com/zelenin/go-tdlib/client" ) func ChatHistory(tdlibClient *client.Client, chatId int64) (chan *client.Message, chan error) { - messageChan := make(chan *client.Message, 10) - errChan := make(chan error, 1) + messageChan := make(chan *client.Message, 10) + errChan := make(chan error, 1) - var fromMessageId int64 = 0 - var offset int32 = 0 - var limit int32 = 100 + var fromMessageId int64 = 0 + var offset int32 = 0 + var limit int32 = 100 - go chatHistory(tdlibClient, messageChan, errChan, chatId, fromMessageId, offset, limit, false) + go chatHistory(tdlibClient, messageChan, errChan, chatId, fromMessageId, offset, limit, false) - return messageChan, errChan + return messageChan, errChan } func chatHistory(tdlibClient *client.Client, messageChan chan *client.Message, errChan chan error, chatId int64, fromMessageId int64, offset int32, limit int32, onlyLocal bool) { - defer func() { - close(messageChan) - close(errChan) - }() + defer func() { + close(messageChan) + close(errChan) + }() - for { - messages, err := tdlibClient.GetChatHistory(&client.GetChatHistoryRequest{ - ChatId: chatId, - FromMessageId: fromMessageId, - Offset: offset, - Limit: limit, - OnlyLocal: onlyLocal, - }) - if err != nil { - errChan <- err + for { + messages, err := tdlibClient.GetChatHistory(&client.GetChatHistoryRequest{ + ChatId: chatId, + FromMessageId: fromMessageId, + Offset: offset, + Limit: limit, + OnlyLocal: onlyLocal, + }) + if err != nil { + errChan <- err - return - } + return + } - if len(messages.Messages) == 0 { - errChan <- EOP + if len(messages.Messages) == 0 { + errChan <- EOP - break - } + break + } - for _, message := range messages.Messages { - fromMessageId = message.Id + for _, message := range messages.Messages { + fromMessageId = message.Id - messageChan <- message - } - } + messageChan <- message + } + } } diff --git a/client/puller/chats.go b/client/puller/chats.go index 5c11aee..27f41c7 100644 --- a/client/puller/chats.go +++ b/client/puller/chats.go @@ -1,62 +1,62 @@ package puller import ( - "math" + "math" - "github.com/zelenin/go-tdlib/client" + "github.com/zelenin/go-tdlib/client" ) func Chats(tdlibClient *client.Client) (chan *client.Chat, chan error) { - chatChan := make(chan *client.Chat, 10) - errChan := make(chan error, 1) + chatChan := make(chan *client.Chat, 10) + errChan := make(chan error, 1) - var offsetOrder client.JsonInt64 = math.MaxInt64 - var offsetChatId int64 = 0 - var limit int32 = 100 + var offsetOrder client.JsonInt64 = math.MaxInt64 + var offsetChatId int64 = 0 + var limit int32 = 100 - go chats(tdlibClient, chatChan, errChan, offsetOrder, offsetChatId, limit) + go chats(tdlibClient, chatChan, errChan, offsetOrder, offsetChatId, limit) - return chatChan, errChan + return chatChan, errChan } func chats(tdlibClient *client.Client, chatChan chan *client.Chat, errChan chan error, offsetOrder client.JsonInt64, offsetChatId int64, limit int32) { - defer func() { - close(chatChan) - close(errChan) - }() + defer func() { + close(chatChan) + close(errChan) + }() - for { - chats, err := tdlibClient.GetChats(&client.GetChatsRequest{ - OffsetOrder: offsetOrder, - OffsetChatId: offsetChatId, - Limit: limit, - }) - if err != nil { - errChan <- err + for { + chats, err := tdlibClient.GetChats(&client.GetChatsRequest{ + OffsetOrder: offsetOrder, + OffsetChatId: offsetChatId, + Limit: limit, + }) + if err != nil { + errChan <- err - return - } + return + } - if len(chats.ChatIds) == 0 { - errChan <- EOP + if len(chats.ChatIds) == 0 { + errChan <- EOP - break - } + break + } - for _, chatId := range chats.ChatIds { - chat, err := tdlibClient.GetChat(&client.GetChatRequest{ - ChatId: chatId, - }) - if err != nil { - errChan <- err + for _, chatId := range chats.ChatIds { + chat, err := tdlibClient.GetChat(&client.GetChatRequest{ + ChatId: chatId, + }) + if err != nil { + errChan <- err - return - } + return + } - offsetOrder = chat.Order - offsetChatId = chat.Id + offsetOrder = chat.Order + offsetChatId = chat.Id - chatChan <- chat - } - } + chatChan <- chat + } + } } diff --git a/client/puller/error.go b/client/puller/error.go index d40b6e4..b82bd18 100644 --- a/client/puller/error.go +++ b/client/puller/error.go @@ -1,7 +1,7 @@ package puller import ( - "errors" + "errors" ) var EOP = errors.New("end of pull") diff --git a/client/puller/supergroup.go b/client/puller/supergroup.go index 69d51bf..89a2693 100644 --- a/client/puller/supergroup.go +++ b/client/puller/supergroup.go @@ -1,53 +1,53 @@ package puller import ( - "github.com/zelenin/go-tdlib/client" + "github.com/zelenin/go-tdlib/client" ) func SupergroupMembers(tdlibClient *client.Client, supergroupId int32) (chan *client.ChatMember, chan error) { - chatMemberChan := make(chan *client.ChatMember, 10) - errChan := make(chan error, 1) + chatMemberChan := make(chan *client.ChatMember, 10) + errChan := make(chan error, 1) - var filter client.SupergroupMembersFilter = nil - var offset int32 = 0 - var limit int32 = 200 + var filter client.SupergroupMembersFilter = nil + var offset int32 = 0 + var limit int32 = 200 - go supergroupMembers(tdlibClient, chatMemberChan, errChan, supergroupId, filter, offset, limit) + go supergroupMembers(tdlibClient, chatMemberChan, errChan, supergroupId, filter, offset, limit) - return chatMemberChan, errChan + return chatMemberChan, errChan } func supergroupMembers(tdlibClient *client.Client, chatMemberChan chan *client.ChatMember, errChan chan error, supergroupId int32, filter client.SupergroupMembersFilter, offset int32, limit int32) { - defer func() { - close(chatMemberChan) - close(errChan) - }() + defer func() { + close(chatMemberChan) + close(errChan) + }() - var page int32 = 0 + var page int32 = 0 - for { - chatMembers, err := tdlibClient.GetSupergroupMembers(&client.GetSupergroupMembersRequest{ - SupergroupId: supergroupId, - Filter: filter, - Offset: page*limit + offset, - Limit: limit, - }) - if err != nil { - errChan <- err + for { + chatMembers, err := tdlibClient.GetSupergroupMembers(&client.GetSupergroupMembersRequest{ + SupergroupId: supergroupId, + Filter: filter, + Offset: page*limit + offset, + Limit: limit, + }) + if err != nil { + errChan <- err - return - } + return + } - if len(chatMembers.Members) == 0 { - errChan <- EOP + if len(chatMembers.Members) == 0 { + errChan <- EOP - break - } + break + } - for _, member := range chatMembers.Members { - chatMemberChan <- member - } + for _, member := range chatMembers.Members { + chatMemberChan <- member + } - page++ - } + page++ + } } diff --git a/cmd/generate-code.go b/cmd/generate-code.go index f4dfc37..baa9223 100644 --- a/cmd/generate-code.go +++ b/cmd/generate-code.go @@ -1,86 +1,86 @@ package main import ( - "bufio" - "flag" - "log" - "net/http" - "os" - "path/filepath" + "bufio" + "flag" + "log" + "net/http" + "os" + "path/filepath" - "github.com/zelenin/go-tdlib/tlparser" - "github.com/zelenin/go-tdlib/codegen" + "github.com/zelenin/go-tdlib/codegen" + "github.com/zelenin/go-tdlib/tlparser" ) type config struct { - version string - outputDirPath string - packageName string - functionFileName string - typeFileName string - unmarshalerFileName string + version string + outputDirPath string + packageName string + functionFileName string + typeFileName string + unmarshalerFileName string } func main() { - var config config + var config config - flag.StringVar(&config.version, "version", "", "TDLib version") - flag.StringVar(&config.outputDirPath, "outputDir", "./tdlib", "output directory") - flag.StringVar(&config.packageName, "package", "tdlib", "package name") - flag.StringVar(&config.functionFileName, "functionFile", "function.go", "functions filename") - flag.StringVar(&config.typeFileName, "typeFile", "type.go", "types filename") - flag.StringVar(&config.unmarshalerFileName, "unmarshalerFile", "unmarshaler.go", "unmarshalers filename") + flag.StringVar(&config.version, "version", "", "TDLib version") + flag.StringVar(&config.outputDirPath, "outputDir", "./tdlib", "output directory") + flag.StringVar(&config.packageName, "package", "tdlib", "package name") + flag.StringVar(&config.functionFileName, "functionFile", "function.go", "functions filename") + flag.StringVar(&config.typeFileName, "typeFile", "type.go", "types filename") + flag.StringVar(&config.unmarshalerFileName, "unmarshalerFile", "unmarshaler.go", "unmarshalers filename") - flag.Parse() + flag.Parse() - resp, err := http.Get("https://raw.githubusercontent.com/tdlib/td/" + config.version + "/td/generate/scheme/td_api.tl") - if err != nil { - log.Fatalf("http.Get error: %s", err) - return - } - defer resp.Body.Close() + resp, err := http.Get("https://raw.githubusercontent.com/tdlib/td/" + config.version + "/td/generate/scheme/td_api.tl") + if err != nil { + log.Fatalf("http.Get error: %s", err) + return + } + defer resp.Body.Close() - schema, err := tlparser.Parse(resp.Body) - if err != nil { - log.Fatalf("schema parse error: %s", err) - return - } + schema, err := tlparser.Parse(resp.Body) + if err != nil { + log.Fatalf("schema parse error: %s", err) + return + } - err = os.MkdirAll(config.outputDirPath, 0755) - if err != nil { - log.Fatalf("error creating %s: %s", config.outputDirPath, err) - } + err = os.MkdirAll(config.outputDirPath, 0755) + if err != nil { + log.Fatalf("error creating %s: %s", config.outputDirPath, err) + } - functionFilePath := filepath.Join(config.outputDirPath, config.functionFileName) + functionFilePath := filepath.Join(config.outputDirPath, config.functionFileName) - os.Remove(functionFilePath) - functionFile, err := os.OpenFile(functionFilePath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm) - if err != nil { - log.Fatalf("functionFile open error: %s", err) - } - defer functionFile.Close() + os.Remove(functionFilePath) + functionFile, err := os.OpenFile(functionFilePath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm) + if err != nil { + log.Fatalf("functionFile open error: %s", err) + } + defer functionFile.Close() - bufio.NewWriter(functionFile).Write(codegen.GenerateFunctions(schema, config.packageName)) + bufio.NewWriter(functionFile).Write(codegen.GenerateFunctions(schema, config.packageName)) - typeFilePath := filepath.Join(config.outputDirPath, config.typeFileName) + typeFilePath := filepath.Join(config.outputDirPath, config.typeFileName) - os.Remove(typeFilePath) - typeFile, err := os.OpenFile(typeFilePath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm) - if err != nil { - log.Fatalf("typeFile open error: %s", err) - } - defer typeFile.Close() + os.Remove(typeFilePath) + typeFile, err := os.OpenFile(typeFilePath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm) + if err != nil { + log.Fatalf("typeFile open error: %s", err) + } + defer typeFile.Close() - bufio.NewWriter(typeFile).Write(codegen.GenerateTypes(schema, config.packageName)) + bufio.NewWriter(typeFile).Write(codegen.GenerateTypes(schema, config.packageName)) - unmarshalerFilePath := filepath.Join(config.outputDirPath, config.unmarshalerFileName) + unmarshalerFilePath := filepath.Join(config.outputDirPath, config.unmarshalerFileName) - os.Remove(unmarshalerFilePath) - unmarshalerFile, err := os.OpenFile(unmarshalerFilePath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm) - if err != nil { - log.Fatalf("unmarshalerFile open error: %s", err) - } - defer unmarshalerFile.Close() + os.Remove(unmarshalerFilePath) + unmarshalerFile, err := os.OpenFile(unmarshalerFilePath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm) + if err != nil { + log.Fatalf("unmarshalerFile open error: %s", err) + } + defer unmarshalerFile.Close() - bufio.NewWriter(unmarshalerFile).Write(codegen.GenerateUnmarshalers(schema, config.packageName)) + bufio.NewWriter(unmarshalerFile).Write(codegen.GenerateUnmarshalers(schema, config.packageName)) } diff --git a/cmd/generate-json.go b/cmd/generate-json.go index f7cedbc..6c2f771 100644 --- a/cmd/generate-json.go +++ b/cmd/generate-json.go @@ -1,67 +1,67 @@ package main import ( - "bufio" - "encoding/json" - "flag" - "log" - "net/http" - "os" - "path/filepath" - "strings" - "github.com/zelenin/go-tdlib/tlparser" + "bufio" + "encoding/json" + "flag" + "github.com/zelenin/go-tdlib/tlparser" + "log" + "net/http" + "os" + "path/filepath" + "strings" ) func main() { - var version string - var outputFilePath string + var version string + var outputFilePath string - flag.StringVar(&version, "version", "", "TDLib version") - flag.StringVar(&outputFilePath, "output", "./td_api.json", "json schema file") + flag.StringVar(&version, "version", "", "TDLib version") + flag.StringVar(&outputFilePath, "output", "./td_api.json", "json schema file") - flag.Parse() + flag.Parse() - resp, err := http.Get("https://raw.githubusercontent.com/tdlib/td/" + version + "/td/generate/scheme/td_api.tl") - if err != nil { - log.Fatalf("http.Get error: %s", err) - return - } - defer resp.Body.Close() + resp, err := http.Get("https://raw.githubusercontent.com/tdlib/td/" + version + "/td/generate/scheme/td_api.tl") + if err != nil { + log.Fatalf("http.Get error: %s", err) + return + } + defer resp.Body.Close() - schema, err := tlparser.Parse(resp.Body) - if err != nil { - log.Fatalf("schema parse error: %s", err) - return - } + schema, err := tlparser.Parse(resp.Body) + if err != nil { + log.Fatalf("schema parse error: %s", err) + return + } - resp, err = http.Get("https://raw.githubusercontent.com/tdlib/td/" + version + "/td/telegram/Td.cpp") - if err != nil { - log.Fatalf("http.Get error: %s", err) - return - } - defer resp.Body.Close() + resp, err = http.Get("https://raw.githubusercontent.com/tdlib/td/" + version + "/td/telegram/Td.cpp") + if err != nil { + log.Fatalf("http.Get error: %s", err) + return + } + defer resp.Body.Close() - err = tlparser.ParseCode(resp.Body, schema) - if err != nil { - log.Fatalf("parse code error: %s", err) - return - } + err = tlparser.ParseCode(resp.Body, schema) + if err != nil { + log.Fatalf("parse code error: %s", err) + return + } - err = os.MkdirAll(filepath.Dir(outputFilePath), os.ModePerm) - if err != nil { - log.Fatalf("make dir error: %s", filepath.Dir(outputFilePath)) - } + err = os.MkdirAll(filepath.Dir(outputFilePath), os.ModePerm) + if err != nil { + log.Fatalf("make dir error: %s", filepath.Dir(outputFilePath)) + } - file, err := os.OpenFile(outputFilePath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm) - if err != nil { - log.Fatalf("open file error: %s", err) - return - } + file, err := os.OpenFile(outputFilePath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm) + if err != nil { + log.Fatalf("open file error: %s", err) + return + } - data, err := json.MarshalIndent(schema, "", strings.Repeat(" ", 4)) - if err != nil { - log.Fatalf("json marshal error: %s", err) - return - } - bufio.NewWriter(file).Write(data) + data, err := json.MarshalIndent(schema, "", strings.Repeat(" ", 4)) + if err != nil { + log.Fatalf("json marshal error: %s", err) + return + } + bufio.NewWriter(file).Write(data) } diff --git a/codegen/function.go b/codegen/function.go index a8a2152..536bde9 100644 --- a/codegen/function.go +++ b/codegen/function.go @@ -1,83 +1,83 @@ package codegen import ( - "bytes" - "fmt" + "bytes" + "fmt" - "github.com/zelenin/go-tdlib/tlparser" + "github.com/zelenin/go-tdlib/tlparser" ) func GenerateFunctions(schema *tlparser.Schema, packageName string) []byte { - buf := bytes.NewBufferString("") + buf := bytes.NewBufferString("") - buf.WriteString(fmt.Sprintf("%s\n\npackage %s\n\n", header, packageName)) + buf.WriteString(fmt.Sprintf("%s\n\npackage %s\n\n", header, packageName)) - buf.WriteString(`import ( + buf.WriteString(`import ( "errors" )`) - buf.WriteString("\n") + buf.WriteString("\n") - for _, function := range schema.Functions { - tdlibFunction := TdlibFunction(function.Name, schema) - tdlibFunctionReturn := TdlibFunctionReturn(function.Class, schema) + for _, function := range schema.Functions { + tdlibFunction := TdlibFunction(function.Name, schema) + tdlibFunctionReturn := TdlibFunctionReturn(function.Class, schema) - if len(function.Properties) > 0 { - buf.WriteString("\n") - buf.WriteString(fmt.Sprintf("type %sRequest struct { \n", tdlibFunction.ToGoName())) - for _, property := range function.Properties { - tdlibTypeProperty := TdlibTypeProperty(property.Name, property.Type, schema) + if len(function.Properties) > 0 { + buf.WriteString("\n") + buf.WriteString(fmt.Sprintf("type %sRequest struct { \n", tdlibFunction.ToGoName())) + for _, property := range function.Properties { + tdlibTypeProperty := TdlibTypeProperty(property.Name, property.Type, schema) - buf.WriteString(fmt.Sprintf(" // %s\n", property.Description)) - buf.WriteString(fmt.Sprintf(" %s %s `json:\"%s\"`\n", tdlibTypeProperty.ToGoName(), tdlibTypeProperty.ToGoType(), property.Name)) - } - buf.WriteString("}\n") - } + buf.WriteString(fmt.Sprintf(" // %s\n", property.Description)) + buf.WriteString(fmt.Sprintf(" %s %s `json:\"%s\"`\n", tdlibTypeProperty.ToGoName(), tdlibTypeProperty.ToGoType(), property.Name)) + } + buf.WriteString("}\n") + } - buf.WriteString("\n") - buf.WriteString("// " + function.Description) - buf.WriteString("\n") + buf.WriteString("\n") + buf.WriteString("// " + function.Description) + buf.WriteString("\n") - requestArgument := "" - if len(function.Properties) > 0 { - requestArgument = fmt.Sprintf("req *%sRequest", tdlibFunction.ToGoName()) - } + requestArgument := "" + if len(function.Properties) > 0 { + requestArgument = fmt.Sprintf("req *%sRequest", tdlibFunction.ToGoName()) + } - buf.WriteString(fmt.Sprintf("func (client *Client) %s(%s) (%s, error) {\n", tdlibFunction.ToGoName(), requestArgument, tdlibFunctionReturn.ToGoReturn())) + buf.WriteString(fmt.Sprintf("func (client *Client) %s(%s) (%s, error) {\n", tdlibFunction.ToGoName(), requestArgument, tdlibFunctionReturn.ToGoReturn())) - sendMethod := "Send" - if function.IsSynchronous { - sendMethod = "jsonClient.Execute" - } + sendMethod := "Send" + if function.IsSynchronous { + sendMethod = "jsonClient.Execute" + } - if len(function.Properties) > 0 { - buf.WriteString(fmt.Sprintf(` result, err := client.%s(Request{ + if len(function.Properties) > 0 { + buf.WriteString(fmt.Sprintf(` result, err := client.%s(Request{ meta: meta{ Type: "%s", }, Data: map[string]interface{}{ `, sendMethod, function.Name)) - for _, property := range function.Properties { - tdlibTypeProperty := TdlibTypeProperty(property.Name, property.Type, schema) + for _, property := range function.Properties { + tdlibTypeProperty := TdlibTypeProperty(property.Name, property.Type, schema) - buf.WriteString(fmt.Sprintf(" \"%s\": req.%s,\n", property.Name, tdlibTypeProperty.ToGoName())) - } + buf.WriteString(fmt.Sprintf(" \"%s\": req.%s,\n", property.Name, tdlibTypeProperty.ToGoName())) + } - buf.WriteString(` }, + buf.WriteString(` }, }) `) - } else { - buf.WriteString(fmt.Sprintf(` result, err := client.%s(Request{ + } else { + buf.WriteString(fmt.Sprintf(` result, err := client.%s(Request{ meta: meta{ Type: "%s", }, Data: map[string]interface{}{}, }) `, sendMethod, function.Name)) - } + } - buf.WriteString(` if err != nil { + buf.WriteString(` if err != nil { return nil, err } @@ -87,29 +87,29 @@ func GenerateFunctions(schema *tlparser.Schema, packageName string) []byte { `) - if tdlibFunctionReturn.IsClass() { - buf.WriteString(" switch result.Type {\n") + if tdlibFunctionReturn.IsClass() { + buf.WriteString(" switch result.Type {\n") - for _, subType := range tdlibFunctionReturn.GetClass().GetSubTypes() { - buf.WriteString(fmt.Sprintf(` case %s: + for _, subType := range tdlibFunctionReturn.GetClass().GetSubTypes() { + buf.WriteString(fmt.Sprintf(` case %s: return Unmarshal%s(result.Data) `, subType.ToTypeConst(), subType.ToGoType())) - } + } - buf.WriteString(` default: + buf.WriteString(` default: return nil, errors.New("invalid type") `) - buf.WriteString(" }\n") - } else { - buf.WriteString(fmt.Sprintf(` return Unmarshal%s(result.Data) + buf.WriteString(" }\n") + } else { + buf.WriteString(fmt.Sprintf(` return Unmarshal%s(result.Data) `, tdlibFunctionReturn.ToGoType())) - } + } - buf.WriteString("}\n") - } + buf.WriteString("}\n") + } - return buf.Bytes() + return buf.Bytes() } diff --git a/codegen/string.go b/codegen/string.go index 6da08ca..0878a17 100644 --- a/codegen/string.go +++ b/codegen/string.go @@ -1,26 +1,26 @@ package codegen import ( - "strings" - "unicode" + "strings" + "unicode" ) func firstUpper(str string) string { - for i, r := range str { - return string(unicode.ToUpper(r)) + str[i+1:] - } + for i, r := range str { + return string(unicode.ToUpper(r)) + str[i+1:] + } - return str + return str } func firstLower(str string) string { - for i, r := range str { - return string(unicode.ToLower(r)) + str[i+1:] - } + for i, r := range str { + return string(unicode.ToLower(r)) + str[i+1:] + } - return str + return str } func underscoreToCamelCase(s string) string { - return strings.Replace(strings.Title(strings.Replace(strings.ToLower(s), "_", " ", -1)), " ", "", -1) + return strings.Replace(strings.Title(strings.Replace(strings.ToLower(s), "_", " ", -1)), " ", "", -1) } diff --git a/codegen/tdlib.go b/codegen/tdlib.go index 43dff53..389497c 100644 --- a/codegen/tdlib.go +++ b/codegen/tdlib.go @@ -1,487 +1,487 @@ package codegen import ( - "github.com/zelenin/go-tdlib/tlparser" - "strings" - "log" + "github.com/zelenin/go-tdlib/tlparser" + "log" + "strings" ) type tdlibFunction struct { - name string - schema *tlparser.Schema + name string + schema *tlparser.Schema } func TdlibFunction(name string, schema *tlparser.Schema) *tdlibFunction { - return &tdlibFunction{ - name: name, - schema: schema, - } + return &tdlibFunction{ + name: name, + schema: schema, + } } func (entity *tdlibFunction) ToGoName() string { - return firstUpper(entity.name) + return firstUpper(entity.name) } type tdlibFunctionReturn struct { - name string - schema *tlparser.Schema + name string + schema *tlparser.Schema } func TdlibFunctionReturn(name string, schema *tlparser.Schema) *tdlibFunctionReturn { - return &tdlibFunctionReturn{ - name: name, - schema: schema, - } + return &tdlibFunctionReturn{ + name: name, + schema: schema, + } } func (entity *tdlibFunctionReturn) IsType() bool { - return isType(entity.name, func(entity *tlparser.Type) string { - return entity.Class - }, entity.schema) + return isType(entity.name, func(entity *tlparser.Type) string { + return entity.Class + }, entity.schema) } func (entity *tdlibFunctionReturn) GetType() *tdlibType { - return getType(entity.name, func(entity *tlparser.Type) string { - return entity.Class - }, entity.schema) + return getType(entity.name, func(entity *tlparser.Type) string { + return entity.Class + }, entity.schema) } func (entity *tdlibFunctionReturn) IsClass() bool { - return isClass(entity.name, func(entity *tlparser.Class) string { - return entity.Name - }, entity.schema) + return isClass(entity.name, func(entity *tlparser.Class) string { + return entity.Name + }, entity.schema) } func (entity *tdlibFunctionReturn) GetClass() *tdlibClass { - return getClass(entity.name, func(entity *tlparser.Class) string { - return entity.Name - }, entity.schema) + return getClass(entity.name, func(entity *tlparser.Class) string { + return entity.Name + }, entity.schema) } func (entity *tdlibFunctionReturn) ToGoReturn() string { - if strings.HasPrefix(entity.name, "vector<") { - log.Fatal("vectors are not supported") - } + if strings.HasPrefix(entity.name, "vector<") { + log.Fatal("vectors are not supported") + } - if entity.IsClass() { - return entity.GetClass().ToGoType() - } + if entity.IsClass() { + return entity.GetClass().ToGoType() + } - if entity.GetType().IsInternal() { - return entity.GetType().ToGoType() - } + if entity.GetType().IsInternal() { + return entity.GetType().ToGoType() + } - return "*" + entity.GetType().ToGoType() + return "*" + entity.GetType().ToGoType() } func (entity *tdlibFunctionReturn) ToGoType() string { - if strings.HasPrefix(entity.name, "vector<") { - log.Fatal("vectors are not supported") - } + if strings.HasPrefix(entity.name, "vector<") { + log.Fatal("vectors are not supported") + } - if entity.IsClass() { - return entity.GetClass().ToGoType() - } + if entity.IsClass() { + return entity.GetClass().ToGoType() + } - return entity.GetType().ToGoType() + return entity.GetType().ToGoType() } type tdlibFunctionProperty struct { - name string - propertyType string - schema *tlparser.Schema + name string + propertyType string + schema *tlparser.Schema } func TdlibFunctionProperty(name string, propertyType string, schema *tlparser.Schema) *tdlibFunctionProperty { - return &tdlibFunctionProperty{ - name: name, - propertyType: propertyType, - schema: schema, - } + return &tdlibFunctionProperty{ + name: name, + propertyType: propertyType, + schema: schema, + } } func (entity *tdlibFunctionProperty) GetPrimitive() string { - primitive := entity.propertyType + primitive := entity.propertyType - for strings.HasPrefix(primitive, "vector<") { - primitive = strings.TrimSuffix(strings.TrimPrefix(primitive, "vector<"), ">") - } + for strings.HasPrefix(primitive, "vector<") { + primitive = strings.TrimSuffix(strings.TrimPrefix(primitive, "vector<"), ">") + } - return primitive + return primitive } func (entity *tdlibFunctionProperty) IsType() bool { - primitive := entity.GetPrimitive() - return isType(primitive, func(entity *tlparser.Type) string { - return entity.Name - }, entity.schema) + primitive := entity.GetPrimitive() + return isType(primitive, func(entity *tlparser.Type) string { + return entity.Name + }, entity.schema) } func (entity *tdlibFunctionProperty) GetType() *tdlibType { - primitive := entity.GetPrimitive() - return getType(primitive, func(entity *tlparser.Type) string { - return entity.Name - }, entity.schema) + primitive := entity.GetPrimitive() + return getType(primitive, func(entity *tlparser.Type) string { + return entity.Name + }, entity.schema) } func (entity *tdlibFunctionProperty) IsClass() bool { - primitive := entity.GetPrimitive() - return isClass(primitive, func(entity *tlparser.Class) string { - return entity.Name - }, entity.schema) + primitive := entity.GetPrimitive() + return isClass(primitive, func(entity *tlparser.Class) string { + return entity.Name + }, entity.schema) } func (entity *tdlibFunctionProperty) GetClass() *tdlibClass { - primitive := entity.GetPrimitive() - return getClass(primitive, func(entity *tlparser.Class) string { - return entity.Name - }, entity.schema) + primitive := entity.GetPrimitive() + return getClass(primitive, func(entity *tlparser.Class) string { + return entity.Name + }, entity.schema) } func (entity *tdlibFunctionProperty) ToGoName() string { - name := firstLower(underscoreToCamelCase(entity.name)) - if name == "type" { - name += "Param" - } + name := firstLower(underscoreToCamelCase(entity.name)) + if name == "type" { + name += "Param" + } - return name + return name } func (entity *tdlibFunctionProperty) ToGoType() string { - tdlibType := entity.propertyType - goType := "" + tdlibType := entity.propertyType + goType := "" - for strings.HasPrefix(tdlibType, "vector<") { - goType = goType + "[]" - tdlibType = strings.TrimSuffix(strings.TrimPrefix(tdlibType, "vector<"), ">") - } + for strings.HasPrefix(tdlibType, "vector<") { + goType = goType + "[]" + tdlibType = strings.TrimSuffix(strings.TrimPrefix(tdlibType, "vector<"), ">") + } - if entity.IsClass() { - return goType + entity.GetClass().ToGoType() - } + if entity.IsClass() { + return goType + entity.GetClass().ToGoType() + } - if entity.GetType().IsInternal() { - return goType + entity.GetType().ToGoType() - } + if entity.GetType().IsInternal() { + return goType + entity.GetType().ToGoType() + } - return goType + "*" + entity.GetType().ToGoType() + return goType + "*" + entity.GetType().ToGoType() } type tdlibType struct { - name string - schema *tlparser.Schema + name string + schema *tlparser.Schema } func TdlibType(name string, schema *tlparser.Schema) *tdlibType { - return &tdlibType{ - name: name, - schema: schema, - } + return &tdlibType{ + name: name, + schema: schema, + } } func (entity *tdlibType) IsInternal() bool { - switch entity.name { - case "double": - return true + switch entity.name { + case "double": + return true - case "string": - return true + case "string": + return true - case "int32": - return true + case "int32": + return true - case "int53": - return true + case "int53": + return true - case "int64": - return true + case "int64": + return true - case "bytes": - return true + case "bytes": + return true - case "boolFalse": - return true + case "boolFalse": + return true - case "boolTrue": - return true + case "boolTrue": + return true - case "vector": - return true - } + case "vector": + return true + } - return false + return false } func (entity *tdlibType) GetType() *tlparser.Type { - name := normalizeEntityName(entity.name) - for _, typ := range entity.schema.Types { - if typ.Name == name { - return typ - } - } - return nil + name := normalizeEntityName(entity.name) + for _, typ := range entity.schema.Types { + if typ.Name == name { + return typ + } + } + return nil } func (entity *tdlibType) ToGoType() string { - if strings.HasPrefix(entity.name, "vector<") { - log.Fatal("vectors are not supported") - } + if strings.HasPrefix(entity.name, "vector<") { + log.Fatal("vectors are not supported") + } - switch entity.name { - case "double": - return "float64" + switch entity.name { + case "double": + return "float64" - case "string": - return "string" + case "string": + return "string" - case "int32": - return "int32" + case "int32": + return "int32" - case "int53": - return "int64" + case "int53": + return "int64" - case "int64": - return "JsonInt64" + case "int64": + return "JsonInt64" - case "bytes": - return "[]byte" + case "bytes": + return "[]byte" - case "boolFalse": - return "bool" + case "boolFalse": + return "bool" - case "boolTrue": - return "bool" - } + case "boolTrue": + return "bool" + } - return firstUpper(entity.name) + return firstUpper(entity.name) } func (entity *tdlibType) ToType() string { - return entity.ToGoType() + "Type" + return entity.ToGoType() + "Type" } func (entity *tdlibType) HasClass() bool { - className := entity.GetType().Class - for _, class := range entity.schema.Classes { - if class.Name == className { - return true - } - } + className := entity.GetType().Class + for _, class := range entity.schema.Classes { + if class.Name == className { + return true + } + } - return false + return false } func (entity *tdlibType) GetClass() *tlparser.Class { - className := entity.GetType().Class - for _, class := range entity.schema.Classes { - if class.Name == className { - return class - } - } + className := entity.GetType().Class + for _, class := range entity.schema.Classes { + if class.Name == className { + return class + } + } - return nil + return nil } func (entity *tdlibType) HasClassProperties() bool { - for _, prop := range entity.GetType().Properties { - tdlibTypeProperty := TdlibTypeProperty(prop.Name, prop.Type, entity.schema) - if tdlibTypeProperty.IsClass() && !tdlibTypeProperty.IsList() { - return true - } + for _, prop := range entity.GetType().Properties { + tdlibTypeProperty := TdlibTypeProperty(prop.Name, prop.Type, entity.schema) + if tdlibTypeProperty.IsClass() && !tdlibTypeProperty.IsList() { + return true + } - } + } - return false + return false } func (entity *tdlibType) IsList() bool { - return strings.HasPrefix(entity.name, "vector<") + return strings.HasPrefix(entity.name, "vector<") } func (entity *tdlibType) ToClassConst() string { - if entity.HasClass() { - return "Class" + TdlibClass(entity.GetType().Class, entity.schema).ToGoType() - } - return "Class" + entity.ToGoType() + if entity.HasClass() { + return "Class" + TdlibClass(entity.GetType().Class, entity.schema).ToGoType() + } + return "Class" + entity.ToGoType() } func (entity *tdlibType) ToTypeConst() string { - return "Type" + entity.ToGoType() + return "Type" + entity.ToGoType() } type tdlibClass struct { - name string - schema *tlparser.Schema + name string + schema *tlparser.Schema } func TdlibClass(name string, schema *tlparser.Schema) *tdlibClass { - return &tdlibClass{ - name: name, - schema: schema, - } + return &tdlibClass{ + name: name, + schema: schema, + } } func (entity *tdlibClass) ToGoType() string { - return firstUpper(entity.name) + return firstUpper(entity.name) } func (entity *tdlibClass) ToType() string { - return entity.ToGoType() + "Type" + return entity.ToGoType() + "Type" } func (entity *tdlibClass) GetSubTypes() []*tdlibType { - types := []*tdlibType{} + types := []*tdlibType{} - for _, t := range entity.schema.Types { - if t.Class == entity.name { - types = append(types, TdlibType(t.Name, entity.schema)) - } - } + for _, t := range entity.schema.Types { + if t.Class == entity.name { + types = append(types, TdlibType(t.Name, entity.schema)) + } + } - return types + return types } func (entity *tdlibClass) ToClassConst() string { - return "Class" + entity.ToGoType() + return "Class" + entity.ToGoType() } type tdlibTypeProperty struct { - name string - propertyType string - schema *tlparser.Schema + name string + propertyType string + schema *tlparser.Schema } func TdlibTypeProperty(name string, propertyType string, schema *tlparser.Schema) *tdlibTypeProperty { - return &tdlibTypeProperty{ - name: name, - propertyType: propertyType, - schema: schema, - } + return &tdlibTypeProperty{ + name: name, + propertyType: propertyType, + schema: schema, + } } func (entity *tdlibTypeProperty) IsList() bool { - return strings.HasPrefix(entity.propertyType, "vector<") + return strings.HasPrefix(entity.propertyType, "vector<") } func (entity *tdlibTypeProperty) GetPrimitive() string { - primitive := entity.propertyType + primitive := entity.propertyType - for strings.HasPrefix(primitive, "vector<") { - primitive = strings.TrimSuffix(strings.TrimPrefix(primitive, "vector<"), ">") - } + for strings.HasPrefix(primitive, "vector<") { + primitive = strings.TrimSuffix(strings.TrimPrefix(primitive, "vector<"), ">") + } - return primitive + return primitive } func (entity *tdlibTypeProperty) IsType() bool { - primitive := entity.GetPrimitive() - return isType(primitive, func(entity *tlparser.Type) string { - return entity.Name - }, entity.schema) + primitive := entity.GetPrimitive() + return isType(primitive, func(entity *tlparser.Type) string { + return entity.Name + }, entity.schema) } func (entity *tdlibTypeProperty) GetType() *tdlibType { - primitive := entity.GetPrimitive() - return getType(primitive, func(entity *tlparser.Type) string { - return entity.Name - }, entity.schema) + primitive := entity.GetPrimitive() + return getType(primitive, func(entity *tlparser.Type) string { + return entity.Name + }, entity.schema) } func (entity *tdlibTypeProperty) IsClass() bool { - primitive := entity.GetPrimitive() - return isClass(primitive, func(entity *tlparser.Class) string { - return entity.Name - }, entity.schema) + primitive := entity.GetPrimitive() + return isClass(primitive, func(entity *tlparser.Class) string { + return entity.Name + }, entity.schema) } func (entity *tdlibTypeProperty) GetClass() *tdlibClass { - primitive := entity.GetPrimitive() - return getClass(primitive, func(entity *tlparser.Class) string { - return entity.Name - }, entity.schema) + primitive := entity.GetPrimitive() + return getClass(primitive, func(entity *tlparser.Class) string { + return entity.Name + }, entity.schema) } func (entity *tdlibTypeProperty) ToGoName() string { - return firstUpper(underscoreToCamelCase(entity.name)) + return firstUpper(underscoreToCamelCase(entity.name)) } func (entity *tdlibTypeProperty) ToGoFunctionPropertyName() string { - name := firstLower(underscoreToCamelCase(entity.name)) - if name == "type" { - name += "Param" - } + name := firstLower(underscoreToCamelCase(entity.name)) + if name == "type" { + name += "Param" + } - return name + return name } func (entity *tdlibTypeProperty) ToGoType() string { - tdlibType := entity.propertyType - goType := "" + tdlibType := entity.propertyType + goType := "" - for strings.HasPrefix(tdlibType, "vector<") { - goType = goType + "[]" - tdlibType = strings.TrimSuffix(strings.TrimPrefix(tdlibType, "vector<"), ">") - } + for strings.HasPrefix(tdlibType, "vector<") { + goType = goType + "[]" + tdlibType = strings.TrimSuffix(strings.TrimPrefix(tdlibType, "vector<"), ">") + } - if entity.IsClass() { - return goType + entity.GetClass().ToGoType() - } + if entity.IsClass() { + return goType + entity.GetClass().ToGoType() + } - if entity.GetType().IsInternal() { - return goType + entity.GetType().ToGoType() - } + if entity.GetType().IsInternal() { + return goType + entity.GetType().ToGoType() + } - return goType + "*" + entity.GetType().ToGoType() + return goType + "*" + entity.GetType().ToGoType() } func isType(name string, field func(entity *tlparser.Type) string, schema *tlparser.Schema) bool { - name = normalizeEntityName(name) - for _, entity := range schema.Types { - if name == field(entity) { - return true - } - } + name = normalizeEntityName(name) + for _, entity := range schema.Types { + if name == field(entity) { + return true + } + } - return false + return false } func getType(name string, field func(entity *tlparser.Type) string, schema *tlparser.Schema) *tdlibType { - name = normalizeEntityName(name) - for _, entity := range schema.Types { - if name == field(entity) { - return TdlibType(entity.Name, schema) - } - } + name = normalizeEntityName(name) + for _, entity := range schema.Types { + if name == field(entity) { + return TdlibType(entity.Name, schema) + } + } - return nil + return nil } func isClass(name string, field func(entity *tlparser.Class) string, schema *tlparser.Schema) bool { - name = normalizeEntityName(name) - for _, entity := range schema.Classes { - if name == field(entity) { - return true - } - } + name = normalizeEntityName(name) + for _, entity := range schema.Classes { + if name == field(entity) { + return true + } + } - return false + return false } func getClass(name string, field func(entity *tlparser.Class) string, schema *tlparser.Schema) *tdlibClass { - name = normalizeEntityName(name) - for _, entity := range schema.Classes { - if name == field(entity) { - return TdlibClass(entity.Name, schema) - } - } + name = normalizeEntityName(name) + for _, entity := range schema.Classes { + if name == field(entity) { + return TdlibClass(entity.Name, schema) + } + } - return nil + return nil } func normalizeEntityName(name string) string { - if name == "Bool" { - name = "boolFalse" - } + if name == "Bool" { + name = "boolFalse" + } - return name + return name } diff --git a/codegen/type.go b/codegen/type.go index 219bdd9..bb1e116 100644 --- a/codegen/type.go +++ b/codegen/type.go @@ -1,91 +1,91 @@ package codegen import ( - "bytes" - "fmt" + "bytes" + "fmt" - "github.com/zelenin/go-tdlib/tlparser" + "github.com/zelenin/go-tdlib/tlparser" ) func GenerateTypes(schema *tlparser.Schema, packageName string) []byte { - buf := bytes.NewBufferString("") + buf := bytes.NewBufferString("") - buf.WriteString(fmt.Sprintf("%s\n\npackage %s\n\n", header, packageName)) + buf.WriteString(fmt.Sprintf("%s\n\npackage %s\n\n", header, packageName)) - buf.WriteString(`import ( + buf.WriteString(`import ( "encoding/json" ) `) - buf.WriteString("const (\n") - for _, entity := range schema.Classes { - tdlibClass := TdlibClass(entity.Name, schema) - buf.WriteString(fmt.Sprintf(" %s = %q\n", tdlibClass.ToClassConst(), entity.Name)) - } - for _, entity := range schema.Types { - tdlibType := TdlibType(entity.Name, schema) - if tdlibType.IsInternal() || tdlibType.HasClass() { - continue - } - buf.WriteString(fmt.Sprintf(" %s = %q\n", tdlibType.ToClassConst(), entity.Class)) - } - buf.WriteString(")") + buf.WriteString("const (\n") + for _, entity := range schema.Classes { + tdlibClass := TdlibClass(entity.Name, schema) + buf.WriteString(fmt.Sprintf(" %s = %q\n", tdlibClass.ToClassConst(), entity.Name)) + } + for _, entity := range schema.Types { + tdlibType := TdlibType(entity.Name, schema) + if tdlibType.IsInternal() || tdlibType.HasClass() { + continue + } + buf.WriteString(fmt.Sprintf(" %s = %q\n", tdlibType.ToClassConst(), entity.Class)) + } + buf.WriteString(")") - buf.WriteString("\n\n") + buf.WriteString("\n\n") - buf.WriteString("const (\n") - for _, entity := range schema.Types { - tdlibType := TdlibType(entity.Name, schema) - if tdlibType.IsInternal() { - continue - } - buf.WriteString(fmt.Sprintf(" %s = %q\n", tdlibType.ToTypeConst(), entity.Name)) - } - buf.WriteString(")") + buf.WriteString("const (\n") + for _, entity := range schema.Types { + tdlibType := TdlibType(entity.Name, schema) + if tdlibType.IsInternal() { + continue + } + buf.WriteString(fmt.Sprintf(" %s = %q\n", tdlibType.ToTypeConst(), entity.Name)) + } + buf.WriteString(")") - buf.WriteString("\n\n") + buf.WriteString("\n\n") - for _, class := range schema.Classes { - tdlibClass := TdlibClass(class.Name, schema) + for _, class := range schema.Classes { + tdlibClass := TdlibClass(class.Name, schema) - buf.WriteString(fmt.Sprintf(`// %s + buf.WriteString(fmt.Sprintf(`// %s type %s interface { %sType() string } `, class.Description, tdlibClass.ToGoType(), tdlibClass.ToGoType())) - } + } - for _, typ := range schema.Types { - tdlibType := TdlibType(typ.Name, schema) - if tdlibType.IsInternal() { - continue - } + for _, typ := range schema.Types { + tdlibType := TdlibType(typ.Name, schema) + if tdlibType.IsInternal() { + continue + } - buf.WriteString("// " + typ.Description + "\n") + buf.WriteString("// " + typ.Description + "\n") - if len(typ.Properties) > 0 { - buf.WriteString(`type ` + tdlibType.ToGoType() + ` struct { + if len(typ.Properties) > 0 { + buf.WriteString(`type ` + tdlibType.ToGoType() + ` struct { meta `) - for _, property := range typ.Properties { - tdlibTypeProperty := TdlibTypeProperty(property.Name, property.Type, schema) + for _, property := range typ.Properties { + tdlibTypeProperty := TdlibTypeProperty(property.Name, property.Type, schema) - buf.WriteString(fmt.Sprintf(" // %s\n", property.Description)) - buf.WriteString(fmt.Sprintf(" %s %s `json:\"%s\"`\n", tdlibTypeProperty.ToGoName(), tdlibTypeProperty.ToGoType(), property.Name)) - } + buf.WriteString(fmt.Sprintf(" // %s\n", property.Description)) + buf.WriteString(fmt.Sprintf(" %s %s `json:\"%s\"`\n", tdlibTypeProperty.ToGoName(), tdlibTypeProperty.ToGoType(), property.Name)) + } - buf.WriteString("}\n\n") - } else { - buf.WriteString(`type ` + tdlibType.ToGoType() + ` struct{ + buf.WriteString("}\n\n") + } else { + buf.WriteString(`type ` + tdlibType.ToGoType() + ` struct{ meta } `) - } + } - buf.WriteString(fmt.Sprintf(`func (entity *%s) MarshalJSON() ([]byte, error) { + buf.WriteString(fmt.Sprintf(`func (entity *%s) MarshalJSON() ([]byte, error) { entity.meta.Type = entity.GetType() type stub %s @@ -95,7 +95,7 @@ type %s interface { `, tdlibType.ToGoType(), tdlibType.ToGoType())) - buf.WriteString(fmt.Sprintf(`func (*%s) GetClass() string { + buf.WriteString(fmt.Sprintf(`func (*%s) GetClass() string { return %s } @@ -105,35 +105,35 @@ func (*%s) GetType() string { `, tdlibType.ToGoType(), tdlibType.ToClassConst(), tdlibType.ToGoType(), tdlibType.ToTypeConst())) - if tdlibType.HasClass() { - tdlibClass := TdlibClass(tdlibType.GetClass().Name, schema) + if tdlibType.HasClass() { + tdlibClass := TdlibClass(tdlibType.GetClass().Name, schema) - buf.WriteString(fmt.Sprintf(`func (*%s) %sType() string { + buf.WriteString(fmt.Sprintf(`func (*%s) %sType() string { return %s } `, tdlibType.ToGoType(), tdlibClass.ToGoType(), tdlibType.ToTypeConst())) - } + } - if tdlibType.HasClassProperties() { - buf.WriteString(fmt.Sprintf(`func (%s *%s) UnmarshalJSON(data []byte) error { + if tdlibType.HasClassProperties() { + buf.WriteString(fmt.Sprintf(`func (%s *%s) UnmarshalJSON(data []byte) error { var tmp struct { `, typ.Name, tdlibType.ToGoType())) - var countSimpleProperties int + var countSimpleProperties int - for _, property := range typ.Properties { - tdlibTypeProperty := TdlibTypeProperty(property.Name, property.Type, schema) + for _, property := range typ.Properties { + tdlibTypeProperty := TdlibTypeProperty(property.Name, property.Type, schema) - if !tdlibTypeProperty.IsClass() || tdlibTypeProperty.IsList() { - buf.WriteString(fmt.Sprintf(" %s %s `json:\"%s\"`\n", tdlibTypeProperty.ToGoName(), tdlibTypeProperty.ToGoType(), property.Name)) - countSimpleProperties++ - } else { - buf.WriteString(fmt.Sprintf(" %s %s `json:\"%s\"`\n", tdlibTypeProperty.ToGoName(), "json.RawMessage", property.Name)) - } - } + if !tdlibTypeProperty.IsClass() || tdlibTypeProperty.IsList() { + buf.WriteString(fmt.Sprintf(" %s %s `json:\"%s\"`\n", tdlibTypeProperty.ToGoName(), tdlibTypeProperty.ToGoType(), property.Name)) + countSimpleProperties++ + } else { + buf.WriteString(fmt.Sprintf(" %s %s `json:\"%s\"`\n", tdlibTypeProperty.ToGoName(), "json.RawMessage", property.Name)) + } + } - buf.WriteString(` } + buf.WriteString(` } err := json.Unmarshal(data, &tmp) if err != nil { @@ -142,35 +142,35 @@ func (*%s) GetType() string { `) - for _, property := range typ.Properties { - tdlibTypeProperty := TdlibTypeProperty(property.Name, property.Type, schema) + for _, property := range typ.Properties { + tdlibTypeProperty := TdlibTypeProperty(property.Name, property.Type, schema) - if !tdlibTypeProperty.IsClass() || tdlibTypeProperty.IsList() { - buf.WriteString(fmt.Sprintf(" %s.%s = tmp.%s\n", typ.Name, tdlibTypeProperty.ToGoName(), tdlibTypeProperty.ToGoName())) - } - } + if !tdlibTypeProperty.IsClass() || tdlibTypeProperty.IsList() { + buf.WriteString(fmt.Sprintf(" %s.%s = tmp.%s\n", typ.Name, tdlibTypeProperty.ToGoName(), tdlibTypeProperty.ToGoName())) + } + } - if countSimpleProperties > 0 { - buf.WriteString("\n") - } + if countSimpleProperties > 0 { + buf.WriteString("\n") + } - for _, property := range typ.Properties { - tdlibTypeProperty := TdlibTypeProperty(property.Name, property.Type, schema) + for _, property := range typ.Properties { + tdlibTypeProperty := TdlibTypeProperty(property.Name, property.Type, schema) - if tdlibTypeProperty.IsClass() && !tdlibTypeProperty.IsList() { - buf.WriteString(fmt.Sprintf(` field%s, _ := Unmarshal%s(tmp.%s) + if tdlibTypeProperty.IsClass() && !tdlibTypeProperty.IsList() { + buf.WriteString(fmt.Sprintf(` field%s, _ := Unmarshal%s(tmp.%s) %s.%s = field%s `, tdlibTypeProperty.ToGoName(), tdlibTypeProperty.ToGoType(), tdlibTypeProperty.ToGoName(), typ.Name, tdlibTypeProperty.ToGoName(), tdlibTypeProperty.ToGoName())) - } - } + } + } - buf.WriteString(` return nil + buf.WriteString(` return nil } `) - } - } + } + } - return buf.Bytes() + return buf.Bytes() } diff --git a/codegen/unmarshaler.go b/codegen/unmarshaler.go index 54e696e..cdee083 100644 --- a/codegen/unmarshaler.go +++ b/codegen/unmarshaler.go @@ -1,27 +1,27 @@ package codegen import ( - "github.com/zelenin/go-tdlib/tlparser" - "fmt" - "bytes" + "bytes" + "fmt" + "github.com/zelenin/go-tdlib/tlparser" ) func GenerateUnmarshalers(schema *tlparser.Schema, packageName string) []byte { - buf := bytes.NewBufferString("") + buf := bytes.NewBufferString("") - buf.WriteString(fmt.Sprintf("%s\n\npackage %s\n\n", header, packageName)) + buf.WriteString(fmt.Sprintf("%s\n\npackage %s\n\n", header, packageName)) - buf.WriteString(`import ( + buf.WriteString(`import ( "encoding/json" "fmt" ) `) - for _, class := range schema.Classes { - tdlibClass := TdlibClass(class.Name, schema) + for _, class := range schema.Classes { + tdlibClass := TdlibClass(class.Name, schema) - buf.WriteString(fmt.Sprintf(`func Unmarshal%s(data json.RawMessage) (%s, error) { + buf.WriteString(fmt.Sprintf(`func Unmarshal%s(data json.RawMessage) (%s, error) { var meta meta err := json.Unmarshal(data, &meta) @@ -32,30 +32,30 @@ func GenerateUnmarshalers(schema *tlparser.Schema, packageName string) []byte { switch meta.Type { `, tdlibClass.ToGoType(), tdlibClass.ToGoType())) - for _, subType := range tdlibClass.GetSubTypes() { - buf.WriteString(fmt.Sprintf(` case %s: + for _, subType := range tdlibClass.GetSubTypes() { + buf.WriteString(fmt.Sprintf(` case %s: return Unmarshal%s(data) `, subType.ToTypeConst(), subType.ToGoType())) - } + } - buf.WriteString(` default: + buf.WriteString(` default: return nil, fmt.Errorf("Error unmarshaling. Unknown type: " + meta.Type) } } `) - } + } - for _, typ := range schema.Types { - tdlibType := TdlibType(typ.Name, schema) + for _, typ := range schema.Types { + tdlibType := TdlibType(typ.Name, schema) - if tdlibType.IsList() || tdlibType.IsInternal() { - continue - } + if tdlibType.IsList() || tdlibType.IsInternal() { + continue + } - buf.WriteString(fmt.Sprintf(`func Unmarshal%s(data json.RawMessage) (*%s, error) { + buf.WriteString(fmt.Sprintf(`func Unmarshal%s(data json.RawMessage) (*%s, error) { var resp %s err := json.Unmarshal(data, &resp) @@ -65,9 +65,9 @@ func GenerateUnmarshalers(schema *tlparser.Schema, packageName string) []byte { `, tdlibType.ToGoType(), tdlibType.ToGoType(), tdlibType.ToGoType())) - } + } - buf.WriteString(`func UnmarshalType(data json.RawMessage) (Type, error) { + buf.WriteString(`func UnmarshalType(data json.RawMessage) (Type, error) { var meta meta err := json.Unmarshal(data, &meta) @@ -78,25 +78,25 @@ func GenerateUnmarshalers(schema *tlparser.Schema, packageName string) []byte { switch meta.Type { `) - for _, typ := range schema.Types { - tdlibType := TdlibType(typ.Name, schema) + for _, typ := range schema.Types { + tdlibType := TdlibType(typ.Name, schema) - if tdlibType.IsList() || tdlibType.IsInternal() { - continue - } + if tdlibType.IsList() || tdlibType.IsInternal() { + continue + } - buf.WriteString(fmt.Sprintf(` case %s: + buf.WriteString(fmt.Sprintf(` case %s: return Unmarshal%s(data) `, tdlibType.ToTypeConst(), tdlibType.ToGoType())) - } + } - buf.WriteString(` default: + buf.WriteString(` default: return nil, fmt.Errorf("Error unmarshaling. Unknown type: " + meta.Type) } } `) - return buf.Bytes() + return buf.Bytes() } diff --git a/tlparser/code.go b/tlparser/code.go index cfc2215..acfbf05 100644 --- a/tlparser/code.go +++ b/tlparser/code.go @@ -1,74 +1,74 @@ package tlparser import ( - "bufio" - "fmt" - "io" - "strings" + "bufio" + "fmt" + "io" + "strings" ) func ParseCode(reader io.Reader, schema *Schema) error { - var prevLine string - var curLine string + var prevLine string + var curLine string - userMethods := map[string]bool{} - botMethods := map[string]bool{} + userMethods := map[string]bool{} + botMethods := map[string]bool{} - scanner := bufio.NewScanner(reader) - for scanner.Scan() { - prevLine = curLine - curLine = scanner.Text() + scanner := bufio.NewScanner(reader) + for scanner.Scan() { + prevLine = curLine + curLine = scanner.Text() - if strings.Contains(curLine, "CHECK_IS_USER();") { - fields := strings.Fields(prevLine) - for _, field := range fields { - var methodName string - n, err := fmt.Sscanf(field, "td_api::%s", &methodName) - if err == nil && n > 0 { - userMethods[methodName] = true - } - } - } + if strings.Contains(curLine, "CHECK_IS_USER();") { + fields := strings.Fields(prevLine) + for _, field := range fields { + var methodName string + n, err := fmt.Sscanf(field, "td_api::%s", &methodName) + if err == nil && n > 0 { + userMethods[methodName] = true + } + } + } - if strings.Contains(curLine, "CHECK_IS_BOT();") { - fields := strings.Fields(prevLine) - for _, field := range fields { - var methodName string - n, err := fmt.Sscanf(field, "td_api::%s", &methodName) - if err == nil && n > 0 { - botMethods[methodName] = true - } - } - } - } + if strings.Contains(curLine, "CHECK_IS_BOT();") { + fields := strings.Fields(prevLine) + for _, field := range fields { + var methodName string + n, err := fmt.Sscanf(field, "td_api::%s", &methodName) + if err == nil && n > 0 { + botMethods[methodName] = true + } + } + } + } - err := scanner.Err() - if err != nil { - return err - } + err := scanner.Err() + if err != nil { + return err + } - var ok bool + var ok bool - for index, _ := range schema.Functions { - hasType := false - _, ok = userMethods[schema.Functions[index].Name] - if ok { - schema.Functions[index].Type = FUNCTION_TYPE_USER - hasType = true - } + for index, _ := range schema.Functions { + hasType := false + _, ok = userMethods[schema.Functions[index].Name] + if ok { + schema.Functions[index].Type = FUNCTION_TYPE_USER + hasType = true + } - _, ok = botMethods[schema.Functions[index].Name] - if ok { - schema.Functions[index].Type = FUNCTION_TYPE_BOT - hasType = true - } + _, ok = botMethods[schema.Functions[index].Name] + if ok { + schema.Functions[index].Type = FUNCTION_TYPE_BOT + hasType = true + } - if !hasType { - schema.Functions[index].Type = FUNCTION_TYPE_COMMON - } + if !hasType { + schema.Functions[index].Type = FUNCTION_TYPE_COMMON + } - ok = false - } + ok = false + } - return nil + return nil } diff --git a/tlparser/parser.go b/tlparser/parser.go index b77a83b..c22b96a 100644 --- a/tlparser/parser.go +++ b/tlparser/parser.go @@ -1,174 +1,174 @@ package tlparser import ( - "io" - "strings" - "bufio" + "bufio" + "io" + "strings" ) func Parse(reader io.Reader) (*Schema, error) { - schema := &Schema{ - Types: []*Type{}, - Classes: []*Class{}, - Functions: []*Function{}, - } + schema := &Schema{ + Types: []*Type{}, + Classes: []*Class{}, + Functions: []*Function{}, + } - scanner := bufio.NewScanner(reader) + scanner := bufio.NewScanner(reader) - hitFunctions := false + hitFunctions := false - for scanner.Scan() { - line := scanner.Text() + for scanner.Scan() { + line := scanner.Text() - switch { - case strings.HasPrefix(line, "//@description"): - if hitFunctions { - schema.Functions = append(schema.Functions, parseFunction(line, scanner)) - } else { - schema.Types = append(schema.Types, parseType(line, scanner)) - } + switch { + case strings.HasPrefix(line, "//@description"): + if hitFunctions { + schema.Functions = append(schema.Functions, parseFunction(line, scanner)) + } else { + schema.Types = append(schema.Types, parseType(line, scanner)) + } - case strings.HasPrefix(line, "//@class"): - schema.Classes = append(schema.Classes, parseClass(line, scanner)) + case strings.HasPrefix(line, "//@class"): + schema.Classes = append(schema.Classes, parseClass(line, scanner)) - case strings.Contains(line, "---functions---"): - hitFunctions = true + case strings.Contains(line, "---functions---"): + hitFunctions = true - case line == "": + case line == "": - default: - bodyFields := strings.Fields(line) - name := bodyFields[0] - class := strings.TrimRight(bodyFields[len(bodyFields)-1], ";") - if hitFunctions { - schema.Functions = append(schema.Functions, &Function{ - Name: name, - Description: "", - Class: class, - Properties: []*Property{}, - IsSynchronous: false, - Type: FUNCTION_TYPE_UNKNOWN, - }) - } else { - if name == "vector" { - name = "vector" - class = "Vector" - } + default: + bodyFields := strings.Fields(line) + name := bodyFields[0] + class := strings.TrimRight(bodyFields[len(bodyFields)-1], ";") + if hitFunctions { + schema.Functions = append(schema.Functions, &Function{ + Name: name, + Description: "", + Class: class, + Properties: []*Property{}, + IsSynchronous: false, + Type: FUNCTION_TYPE_UNKNOWN, + }) + } else { + if name == "vector" { + name = "vector" + class = "Vector" + } - schema.Types = append(schema.Types, &Type{ - Name: name, - Description: "", - Class: class, - Properties: []*Property{}, - }) - } - } - } + schema.Types = append(schema.Types, &Type{ + Name: name, + Description: "", + Class: class, + Properties: []*Property{}, + }) + } + } + } - return schema, nil + return schema, nil } func parseType(firstLine string, scanner *bufio.Scanner) *Type { - name, description, class, properties, _ := parseEntity(firstLine, scanner) - return &Type{ - Name: name, - Description: description, - Class: class, - Properties: properties, - } + name, description, class, properties, _ := parseEntity(firstLine, scanner) + return &Type{ + Name: name, + Description: description, + Class: class, + Properties: properties, + } } func parseFunction(firstLine string, scanner *bufio.Scanner) *Function { - name, description, class, properties, isSynchronous := parseEntity(firstLine, scanner) - return &Function{ - Name: name, - Description: description, - Class: class, - Properties: properties, - IsSynchronous: isSynchronous, - Type: FUNCTION_TYPE_UNKNOWN, - } + name, description, class, properties, isSynchronous := parseEntity(firstLine, scanner) + return &Function{ + Name: name, + Description: description, + Class: class, + Properties: properties, + IsSynchronous: isSynchronous, + Type: FUNCTION_TYPE_UNKNOWN, + } } func parseClass(firstLine string, scanner *bufio.Scanner) *Class { - class := &Class{ - Name: "", - Description: "", - } + class := &Class{ + Name: "", + Description: "", + } - classLineParts := strings.Split(firstLine, "@") + classLineParts := strings.Split(firstLine, "@") - _, class.Name = parseProperty(classLineParts[1]) - _, class.Description = parseProperty(classLineParts[2]) + _, class.Name = parseProperty(classLineParts[1]) + _, class.Description = parseProperty(classLineParts[2]) - return class + return class } func parseEntity(firstLine string, scanner *bufio.Scanner) (string, string, string, []*Property, bool) { - name := "" - description := "" - class := "" - properties := []*Property{} + name := "" + description := "" + class := "" + properties := []*Property{} - propertiesLine := strings.TrimLeft(firstLine, "//") + propertiesLine := strings.TrimLeft(firstLine, "//") Loop: - for scanner.Scan() { - line := scanner.Text() + for scanner.Scan() { + line := scanner.Text() - switch { - case strings.HasPrefix(line, "//@"): - propertiesLine += " " + strings.TrimLeft(line, "//") + switch { + case strings.HasPrefix(line, "//@"): + propertiesLine += " " + strings.TrimLeft(line, "//") - case strings.HasPrefix(line, "//-"): - propertiesLine += " " + strings.TrimLeft(line, "//-") + case strings.HasPrefix(line, "//-"): + propertiesLine += " " + strings.TrimLeft(line, "//-") - default: - bodyFields := strings.Fields(line) - name = bodyFields[0] + default: + bodyFields := strings.Fields(line) + name = bodyFields[0] - for _, rawProperty := range bodyFields[1 : len(bodyFields)-2] { - propertyParts := strings.Split(rawProperty, ":") - property := &Property{ - Name: propertyParts[0], - Type: propertyParts[1], - } - properties = append(properties, property) - } - class = strings.TrimRight(bodyFields[len(bodyFields)-1], ";") - break Loop - } - } + for _, rawProperty := range bodyFields[1 : len(bodyFields)-2] { + propertyParts := strings.Split(rawProperty, ":") + property := &Property{ + Name: propertyParts[0], + Type: propertyParts[1], + } + properties = append(properties, property) + } + class = strings.TrimRight(bodyFields[len(bodyFields)-1], ";") + break Loop + } + } - rawProperties := strings.Split(propertiesLine, "@") - for _, rawProperty := range rawProperties[1:] { - name, value := parseProperty(rawProperty) - switch { - case name == "description": - description = value - default: - name = strings.TrimPrefix(name, "param_") - property := getProperty(properties, name) - property.Description = value + rawProperties := strings.Split(propertiesLine, "@") + for _, rawProperty := range rawProperties[1:] { + name, value := parseProperty(rawProperty) + switch { + case name == "description": + description = value + default: + name = strings.TrimPrefix(name, "param_") + property := getProperty(properties, name) + property.Description = value - } - } + } + } - return name, description, class, properties, strings.Contains(description, "Can be called synchronously") + return name, description, class, properties, strings.Contains(description, "Can be called synchronously") } func parseProperty(str string) (string, string) { - strParts := strings.Fields(str) + strParts := strings.Fields(str) - return strParts[0], strings.Join(strParts[1:], " ") + return strParts[0], strings.Join(strParts[1:], " ") } func getProperty(properties []*Property, name string) *Property { - for _, property := range properties { - if property.Name == name { - return property - } - } + for _, property := range properties { + if property.Name == name { + return property + } + } - return nil + return nil } diff --git a/tlparser/type.go b/tlparser/type.go index dd791a8..5948fe1 100644 --- a/tlparser/type.go +++ b/tlparser/type.go @@ -1,43 +1,43 @@ package tlparser type Schema struct { - Types []*Type `json:"types"` - Classes []*Class `json:"classes"` - Functions []*Function `json:"functions"` + Types []*Type `json:"types"` + Classes []*Class `json:"classes"` + Functions []*Function `json:"functions"` } type Type struct { - Name string `json:"name"` - Description string `json:"description"` - Class string `json:"class"` - Properties []*Property `json:"properties"` + Name string `json:"name"` + Description string `json:"description"` + Class string `json:"class"` + Properties []*Property `json:"properties"` } type Class struct { - Name string `json:"name"` - Description string `json:"description"` + Name string `json:"name"` + Description string `json:"description"` } type FunctionType int const ( - FUNCTION_TYPE_UNKNOWN FunctionType = iota - FUNCTION_TYPE_COMMON - FUNCTION_TYPE_USER - FUNCTION_TYPE_BOT + FUNCTION_TYPE_UNKNOWN FunctionType = iota + FUNCTION_TYPE_COMMON + FUNCTION_TYPE_USER + FUNCTION_TYPE_BOT ) type Function struct { - Name string `json:"name"` - Description string `json:"description"` - Class string `json:"class"` - Properties []*Property `json:"properties"` - IsSynchronous bool `json:"is_synchronous"` - Type FunctionType `json:"type"` + Name string `json:"name"` + Description string `json:"description"` + Class string `json:"class"` + Properties []*Property `json:"properties"` + IsSynchronous bool `json:"is_synchronous"` + Type FunctionType `json:"type"` } type Property struct { - Name string `json:"name"` - Type string `json:"type"` - Description string `json:"description"` + Name string `json:"name"` + Type string `json:"type"` + Description string `json:"description"` }