Skip to content

Commit 70b7083

Browse files
committedSep 30, 2020
Merge branch 'master' of github.com:pacedotdev/oto
2 parents 24a8bc8 + 70db1dc commit 70b7083

File tree

11 files changed

+227
-60
lines changed

11 files changed

+227
-60
lines changed
 

‎example/client.swift.plush

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Code generated by oto; DO NOT EDIT.
2+
3+
import Foundation
4+
5+
class OtoClient {
6+
var endpoint: String
7+
init(withEndpoint url: String) {
8+
self.endpoint = url
9+
}
10+
}
11+
12+
<%= for (service) in def.Services { %>
13+
<%= format_comment_text(service.Comment) %>class <%= service.Name %> {
14+
var client: OtoClient
15+
init(withClient client: OtoClient) {
16+
self.client = client
17+
}
18+
<%= for (method) in service.Methods { %>
19+
<%= format_comment_text(method.Comment) %> func <%= camelize_down(method.Name) %>(withRequest <%= camelize_down(method.InputObject.TypeName) %>: <%= method.InputObject.TypeName %>, completion: @escaping (_ response: <%= method.OutputObject.TypeName %>?, _ error: Error?) -> ()) {
20+
var request = URLRequest(url: URL(string: "\(self.client.endpoint)/<%= service.Name %>.<%= method.Name %>")!)
21+
request.httpMethod = "POST"
22+
request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
23+
request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept")
24+
var jsonData: Data
25+
do {
26+
jsonData = try JSONEncoder().encode(<%= camelize_down(method.InputObject.TypeName) %>)
27+
} catch let err {
28+
completion(nil, err)
29+
return
30+
}
31+
request.httpBody = jsonData
32+
let session = URLSession(configuration: URLSessionConfiguration.default)
33+
let task = session.dataTask(with: request) { (data, response, error) in
34+
if let err = error {
35+
completion(nil, err)
36+
return
37+
}
38+
var <%= camelize_down(method.OutputObject.TypeName) %>: <%= method.OutputObject.TypeName %>
39+
do {
40+
<%= camelize_down(method.OutputObject.TypeName) %> = try JSONDecoder().decode(<%= method.OutputObject.TypeName %>.self, from: data!)
41+
} catch let err {
42+
completion(nil, err)
43+
return
44+
}
45+
completion(<%= camelize_down(method.OutputObject.TypeName) %>, nil)
46+
}
47+
task.resume()
48+
}
49+
<% } %>
50+
}
51+
<% } %>
52+
53+
<%= for (object) in def.Objects { %>
54+
<%= format_comment_text(object.Comment) %>struct <%= object.Name %>: Encodable, Decodable {
55+
<%= for (field) in object.Fields { %>
56+
<%= format_comment_text(field.Comment) %> var <%= camelize_down(field.Name) %>: <%= field.Type.SwiftType %>?
57+
<% } %>
58+
}
59+
<% } %>

‎example/def/greeter_service.go

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package def
22

33
// GreeterService is a polite API for greeting people.
44
type GreeterService interface {
5+
// Greet prepares a lovely greeting.
56
Greet(GreetRequest) GreetResponse
67
}
78

‎example/generate.sh

+6
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,9 @@ oto -template client.js.plush \
1212
-pkg main \
1313
./def
1414
echo "generated client.gen.js"
15+
16+
oto -template client.swift.plush \
17+
-out ./swift/SwiftCLIExample/SwiftCLIExample/client.gen.swift \
18+
-pkg main \
19+
./def
20+
echo "generated client.gen.swift"

‎example/server.gen.go

+1-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎example/swift/SwiftCLIExample/SwiftCLIExample.xcodeproj/project.pbxproj

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
/* Begin PBXBuildFile section */
1010
0536E5D225222EB200E82696 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0536E5D125222EB200E82696 /* main.swift */; };
11+
0536E5DF2523678400E82696 /* client.gen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0536E5DE2523678400E82696 /* client.gen.swift */; };
1112
/* End PBXBuildFile section */
1213

1314
/* Begin PBXCopyFilesBuildPhase section */
@@ -25,6 +26,7 @@
2526
/* Begin PBXFileReference section */
2627
0536E5CE25222EB200E82696 /* SwiftCLIExample */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SwiftCLIExample; sourceTree = BUILT_PRODUCTS_DIR; };
2728
0536E5D125222EB200E82696 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
29+
0536E5DE2523678400E82696 /* client.gen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = client.gen.swift; sourceTree = "<group>"; };
2830
/* End PBXFileReference section */
2931

3032
/* Begin PBXFrameworksBuildPhase section */
@@ -58,6 +60,7 @@
5860
isa = PBXGroup;
5961
children = (
6062
0536E5D125222EB200E82696 /* main.swift */,
63+
0536E5DE2523678400E82696 /* client.gen.swift */,
6164
);
6265
path = SwiftCLIExample;
6366
sourceTree = "<group>";
@@ -119,6 +122,7 @@
119122
isa = PBXSourcesBuildPhase;
120123
buildActionMask = 2147483647;
121124
files = (
125+
0536E5DF2523678400E82696 /* client.gen.swift in Sources */,
122126
0536E5D225222EB200E82696 /* main.swift in Sources */,
123127
);
124128
runOnlyForDeploymentPostprocessing = 0;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Code generated by oto; DO NOT EDIT.
2+
3+
import Foundation
4+
5+
class OtoClient {
6+
var endpoint: String
7+
init(withEndpoint url: String) {
8+
self.endpoint = url
9+
}
10+
}
11+
12+
13+
// GreeterService is a polite API for greeting people.
14+
class GreeterService {
15+
var client: OtoClient
16+
init(withClient client: OtoClient) {
17+
self.client = client
18+
}
19+
20+
// Greet prepares a lovely greeting.
21+
func greet(withRequest greetRequest: GreetRequest, completion: @escaping (_ response: GreetResponse?, _ error: Error?) -> ()) {
22+
var request = URLRequest(url: URL(string: "\(self.client.endpoint)/GreeterService.Greet")!)
23+
request.httpMethod = "POST"
24+
request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
25+
request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept")
26+
var jsonData: Data
27+
do {
28+
jsonData = try JSONEncoder().encode(greetRequest)
29+
} catch let err {
30+
completion(nil, err)
31+
return
32+
}
33+
request.httpBody = jsonData
34+
let session = URLSession(configuration: URLSessionConfiguration.default)
35+
let task = session.dataTask(with: request) { (data, response, error) in
36+
if let err = error {
37+
completion(nil, err)
38+
return
39+
}
40+
var greetResponse: GreetResponse
41+
do {
42+
greetResponse = try JSONDecoder().decode(GreetResponse.self, from: data!)
43+
} catch let err {
44+
completion(nil, err)
45+
return
46+
}
47+
completion(greetResponse, nil)
48+
}
49+
task.resume()
50+
}
51+
52+
}
53+
54+
55+
56+
// GreetRequest is the request object for GreeterService.Greet.
57+
struct GreetRequest: Encodable, Decodable {
58+
59+
// Name is the person to greet. It is required.
60+
var name: String?
61+
62+
}
63+
64+
// GreetResponse is the response object containing a person's greeting.
65+
struct GreetResponse: Encodable, Decodable {
66+
67+
// Greeting is a nice message welcoming somebody.
68+
var greeting: String?
69+
70+
// Error is string explaining what went wrong. Empty if everything was fine.
71+
var error: String?
72+
73+
}
74+

‎example/swift/SwiftCLIExample/SwiftCLIExample/main.swift

+8-56
Original file line numberDiff line numberDiff line change
@@ -8,65 +8,17 @@
88
import Foundation
99

1010
let client = OtoClient(withEndpoint: "http://localhost:8080/oto")
11-
let service = MyService(withClient: client)
11+
let greeterService = GreeterService(withClient: client)
1212

13-
service.doSomething(withRequest: DoSomethingRequest(
13+
greeterService.greet(withRequest: GreetRequest(
1414
name: "Mat"
1515
)) { (response, err) -> () in
16-
print("done")
17-
}
18-
19-
class OtoClient {
20-
var endpoint: String
21-
init(withEndpoint url: String) {
22-
self.endpoint = url
16+
if let err = err {
17+
print("ERROR: \(err)")
18+
return
2319
}
20+
print(response!.greeting!)
2421
}
2522

26-
class MyService {
27-
var client: OtoClient
28-
init(withClient client: OtoClient) {
29-
self.client = client
30-
}
31-
func doSomething(withRequest doSomethingRequest: DoSomethingRequest, completion: (_ response: DoSomethingResponse?, _ error: Error?) -> ()) {
32-
//var request = URLRequest(url: URL(string: "\(self.client.endpoint)/MyService/MyMethod")!)
33-
// https://jsonplaceholder.typicode.com/todos/1
34-
var request = URLRequest(url: URL(string: "https://jsonplaceholder.typicode.com/todos/1")!)
35-
36-
request.httpMethod = "POST"
37-
request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
38-
request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept")
39-
var jsonData: Data
40-
do {
41-
jsonData = try JSONEncoder().encode(doSomethingRequest)
42-
} catch let jsonEncodeErr {
43-
print("TODO: handle JSON encode error: \(jsonEncodeErr)")
44-
return
45-
}
46-
request.httpBody = jsonData
47-
let session = URLSession(configuration: URLSessionConfiguration.default)
48-
let task = session.dataTask(with: request) { (data, response, error) in
49-
if let err = error {
50-
print("TODO: handle response error: \(err)")
51-
return
52-
}
53-
var doSomethingResponse: DoSomethingResponse
54-
do {
55-
doSomethingResponse = try JSONDecoder().decode(DoSomethingResponse.self, from: data!)
56-
} catch let err {
57-
print("TODO: handle JSON decode error: \(err)")
58-
return
59-
}
60-
print("\(doSomethingResponse)")
61-
}
62-
task.resume()
63-
}
64-
}
65-
66-
struct DoSomethingRequest: Encodable {
67-
var name: String = ""
68-
}
69-
70-
struct DoSomethingResponse: Decodable {
71-
var greeting: String = ""
72-
}
23+
print("hi")
24+
sleep(1)

‎otohttp/templates/client.swift.plush

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Code generated by oto; DO NOT EDIT.
2+
3+
import Foundation
4+
5+
class OtoClient {
6+
var endpoint: String
7+
init(withEndpoint url: String) {
8+
self.endpoint = url
9+
}
10+
}
11+
12+
<%= for (service) in def.Services { %>
13+
<%= format_comment_text(service.Comment) %>class <%= service.Name %> {
14+
var client: OtoClient
15+
init(withClient client: OtoClient) {
16+
self.client = client
17+
}
18+
<%= for (method) in service.Methods { %>
19+
<%= format_comment_text(method.Comment) %> func <%= camelize_down(method.Name) %>(withRequest <%= camelize_down(method.InputObject.TypeName) %>: <%= method.InputObject.TypeName %>, completion: @escaping (_ response: <%= method.OutputObject.TypeName %>?, _ error: Error?) -> ()) {
20+
var request = URLRequest(url: URL(string: "\(self.client.endpoint)/<%= service.Name %>.<%= method.Name %>")!)
21+
request.httpMethod = "POST"
22+
request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
23+
request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept")
24+
var jsonData: Data
25+
do {
26+
jsonData = try JSONEncoder().encode(<%= camelize_down(method.InputObject.TypeName) %>)
27+
} catch let err {
28+
completion(nil, err)
29+
return
30+
}
31+
request.httpBody = jsonData
32+
let session = URLSession(configuration: URLSessionConfiguration.default)
33+
let task = session.dataTask(with: request) { (data, response, error) in
34+
if let err = error {
35+
completion(nil, err)
36+
return
37+
}
38+
var <%= camelize_down(method.OutputObject.TypeName) %>: <%= method.OutputObject.TypeName %>
39+
do {
40+
<%= camelize_down(method.OutputObject.TypeName) %> = try JSONDecoder().decode(<%= method.OutputObject.TypeName %>.self, from: data!)
41+
} catch let err {
42+
completion(nil, err)
43+
return
44+
}
45+
completion(<%= camelize_down(method.OutputObject.TypeName) %>, nil)
46+
}
47+
task.resume()
48+
}
49+
<% } %>
50+
}
51+
<% } %>
52+
53+
<%= for (object) in def.Objects { %>
54+
<%= format_comment_text(object.Comment) %>struct <%= object.Name %>: Encodable, Decodable {
55+
<%= for (field) in object.Fields { %>
56+
<%= format_comment_text(field.Comment) %> var <%= camelize_down(field.Name) %>: <%= field.Type.SwiftType %>?
57+
<% } %>
58+
}
59+
<% } %>

‎parser/parser.go

+10-2
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ type FieldType struct {
114114
Package string `json:"package"`
115115
IsObject bool `json:"isObject"`
116116
JSType string `json:"jsType"`
117+
SwiftType string `json:"swiftType"`
117118
}
118119

119120
// Parser parses Oto Go definition packages.
@@ -378,20 +379,26 @@ func (p *Parser) parseFieldType(pkg *packages.Package, obj types.Object) (FieldT
378379
ftype.TypeID = pkgPath + "." + ftype.ObjectName
379380
if ftype.IsObject {
380381
ftype.JSType = "object"
382+
ftype.SwiftType = "Any"
381383
} else {
382384
switch ftype.TypeName {
383385
case "interface{}":
384386
ftype.JSType = "any"
387+
ftype.SwiftType = "Any"
385388
case "map[string]interface{}":
386389
ftype.JSType = "object"
390+
ftype.SwiftType = "Any"
387391
case "string":
388392
ftype.JSType = "string"
393+
ftype.SwiftType = "String"
389394
case "bool":
390395
ftype.JSType = "boolean"
396+
ftype.SwiftType = "Bool"
391397
case "int", "int16", "int32", "int64",
392398
"uint", "uint16", "uint32", "uint64",
393399
"float32", "float64":
394400
ftype.JSType = "number"
401+
ftype.SwiftType = "Double"
395402
}
396403
}
397404

@@ -407,8 +414,9 @@ func (p *Parser) addOutputFields() error {
407414
NameLowerCamel: "error",
408415
Comment: "Error is string explaining what went wrong. Empty if everything was fine.",
409416
Type: FieldType{
410-
TypeName: "string",
411-
JSType: "string",
417+
TypeName: "string",
418+
JSType: "string",
419+
SwiftType: "String",
412420
},
413421
Metadata: map[string]interface{}{},
414422
Example: "something went wrong",

‎parser/parser_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,18 @@ You will love it.`)
133133
is.Equal(welcomeInputObject.Fields[1].OmitEmpty, false)
134134
is.Equal(welcomeInputObject.Fields[1].Type.TypeName, "string")
135135
is.Equal(welcomeInputObject.Fields[1].Type.JSType, "string")
136+
is.Equal(welcomeInputObject.Fields[1].Type.SwiftType, "String")
136137
is.Equal(welcomeInputObject.Fields[1].Type.Multiple, false)
137138
is.Equal(welcomeInputObject.Fields[1].Type.Package, "")
138139
is.Equal(welcomeInputObject.Fields[1].Example, "John Smith")
139140

140141
is.Equal(welcomeInputObject.Fields[2].Example, float64(3))
141142
is.Equal(welcomeInputObject.Fields[2].Type.JSType, "number")
143+
is.Equal(welcomeInputObject.Fields[2].Type.SwiftType, "Double")
142144

143145
is.Equal(welcomeInputObject.Fields[3].Example, true)
144146
is.Equal(welcomeInputObject.Fields[3].Type.JSType, "boolean")
147+
is.Equal(welcomeInputObject.Fields[3].Type.SwiftType, "Bool")
145148

146149
welcomeOutputObject, err := def.Object(def.Services[1].Methods[0].OutputObject.TypeName)
147150
is.NoErr(err)
@@ -160,6 +163,8 @@ You will love it.`)
160163
is.Equal(welcomeOutputObject.Fields[1].Type.TypeName, "string")
161164
is.Equal(welcomeOutputObject.Fields[1].Type.Multiple, false)
162165
is.Equal(welcomeOutputObject.Fields[1].Type.Package, "")
166+
is.Equal(welcomeOutputObject.Fields[1].Type.JSType, "string")
167+
is.Equal(welcomeOutputObject.Fields[1].Type.SwiftType, "String")
163168
is.True(welcomeOutputObject.Metadata != nil)
164169

165170
is.Equal(len(def.Objects), 8)

0 commit comments

Comments
 (0)
Please sign in to comment.