Skip to content

Commit 72e7ad9

Browse files
Move JSONRPCParameter to separate file.
1 parent 88c84bb commit 72e7ad9

File tree

2 files changed

+194
-189
lines changed

2 files changed

+194
-189
lines changed

Sources/web3swift/Web3/Web3+JSONRPC.swift

Lines changed: 0 additions & 189 deletions
Original file line numberDiff line numberDiff line change
@@ -285,192 +285,3 @@ public struct EventFilterParameters: Codable {
285285
public var topics: [[String?]?]?
286286
public var address: [String?]?
287287
}
288-
289-
/// Protocol to restrict supported types which can be passed into `JSONRPCRequest` to a node.
290-
///
291-
/// You **must not** conform any type to that protocol.
292-
///
293-
/// Due to internal logic and swift itself restrictions, there's lack of encoding generic types
294-
/// so current implementation of `JSONRPCParameter`s belongs on hardcoded supported types.
295-
///
296-
/// Conformance of that protocol by a custom type will be silently failed to encode (e.g. there won't be in request).
297-
///
298-
/// Please see `RPCParameter` documentation for more details.
299-
public protocol JSONRPCParameter: Encodable { }
300-
301-
protocol JSONParameterElement: Encodable { }
302-
303-
extension Int: JSONRPCParameter { }
304-
305-
extension UInt: JSONRPCParameter { }
306-
307-
extension UInt64: JSONRPCParameter { }
308-
309-
extension Double: JSONRPCParameter { }
310-
311-
extension String: JSONRPCParameter { }
312-
313-
extension Bool: JSONRPCParameter { }
314-
315-
extension Array: JSONRPCParameter where Element: JSONParameterElement { }
316-
317-
extension TransactionParameters: JSONRPCParameter { }
318-
319-
extension EventFilterParameters: JSONRPCParameter { }
320-
321-
extension Double: JSONParameterElement { }
322-
323-
extension Int: JSONParameterElement { }
324-
325-
extension UInt64: JSONParameterElement { }
326-
327-
extension String: JSONParameterElement { }
328-
329-
/**
330-
Enum to compose request to the node params.
331-
332-
In most cases request params are passed to Ethereum JSON RPC request as array of mixed type values, such as `[12,"this",true]`,
333-
thus this is not appropriate API design we have what we have.
334-
335-
Meanwhile swift don't provide strict way to compose such array it gives some hacks to solve this task
336-
and one of them is using `RawRepresentable` protocol.
337-
338-
Conforming this protocol gives designated type ability to represent itself in `String` representation in any way.
339-
340-
So in our case we're using such to implement custom `encode` method to any used in node request params types.
341-
342-
Latter is required to encode array of `RPCParameter` to not to `[RPCParameter.int(1)]`, but to `[1]`.
343-
344-
Here's an example of using this enum in field.
345-
```swift
346-
let jsonRPCParams: [JSONRPCParameter] = [
347-
.init(rawValue: 12)!,
348-
.init(rawValue: "this")!,
349-
.init(rawValue: 12.2)!,
350-
.init(rawValue: [12.2, 12.4])!
351-
]
352-
let encoded = try JSONEncoder().encode(jsonRPCParams)
353-
print(String(data: encoded, encoding: .utf8)!)
354-
//> [12,\"this\",12.2,[12.2,12.4]]`
355-
```
356-
*/
357-
public enum RPCParameter {
358-
case int(Int)
359-
case intArray([Int])
360-
361-
case uint(UInt64)
362-
case uintArray([UInt64])
363-
364-
case double(Double)
365-
case doubleArray([Double])
366-
367-
case string(String)
368-
case stringArray([String])
369-
370-
case bool(Bool)
371-
case transaction(TransactionParameters)
372-
case eventFilter(EventFilterParameters)
373-
}
374-
375-
376-
extension RPCParameter: RawRepresentable {
377-
/**
378-
This init required by `RawRepresentable` protocol, which is requred to encode mixed type values array in JSON.
379-
380-
This protocol used to implement custom `encode` method for that enum,
381-
which is encodes array of self into array of self assotiated values.
382-
383-
You're totally free to use explicit and more convenience member init as `RPCParameter.int(12)` in your code.
384-
*/
385-
public init?(rawValue: JSONRPCParameter) {
386-
/// force casting in this switch is safe because
387-
/// each `rawValue` forced to casts only in exact case which is runs based on `rawValues` type
388-
// swiftlint:disable force_cast
389-
switch type(of: rawValue) {
390-
case is Int.Type: self = .int(rawValue as! Int)
391-
case is [Int].Type: self = .intArray(rawValue as! [Int])
392-
393-
case is UInt64.Type: self = .uint(rawValue as! UInt64)
394-
case is [UInt64].Type: self = .uintArray(rawValue as! [UInt64])
395-
396-
case is String.Type: self = .string(rawValue as! String)
397-
case is [String].Type: self = .stringArray(rawValue as! [String])
398-
399-
case is Double.Type: self = .double(rawValue as! Double)
400-
case is [Double].Type: self = .doubleArray(rawValue as! [Double])
401-
402-
case is Bool.Type: self = .bool(rawValue as! Bool)
403-
case is TransactionParameters.Type: self = .transaction(rawValue as! TransactionParameters)
404-
case is EventFilterParameters.Type: self = .eventFilter(rawValue as! EventFilterParameters)
405-
default: return nil
406-
}
407-
// swiftlint:enable force_cast
408-
}
409-
410-
/// Returning associated value of the enum case.
411-
public var rawValue: JSONRPCParameter {
412-
// cases can't be merged, coz it cause compiler error since it couldn't predict what exact type on exact case will be returned.
413-
switch self {
414-
case let .int(value): return value
415-
case let .intArray(value): return value
416-
417-
case let .uint(value): return value
418-
case let .uintArray(value): return value
419-
420-
case let .string(value): return value
421-
case let .stringArray(value): return value
422-
423-
case let .double(value): return value
424-
case let .doubleArray(value): return value
425-
426-
case let .bool(value): return value
427-
case let .transaction(value): return value
428-
case let .eventFilter(value): return value
429-
}
430-
}
431-
}
432-
433-
extension RPCParameter: Encodable {
434-
/**
435-
This encoder encodes `RPCParameter` assotiated value ignoring self value
436-
437-
This is required to encode mixed types array, like
438-
439-
```swift
440-
let someArray: [RPCParameter] = [
441-
.init(rawValue: 12)!,
442-
.init(rawValue: "this")!,
443-
.init(rawValue: 12.2)!,
444-
.init(rawValue: [12.2, 12.4])!
445-
]
446-
let encoded = try JSONEncoder().encode(someArray)
447-
print(String(data: encoded, encoding: .utf8)!)
448-
//> [12,\"this\",12.2,[12.2,12.4]]`
449-
```
450-
*/
451-
public func encode(to encoder: Encoder) throws {
452-
var enumContainer = encoder.singleValueContainer()
453-
/// force casting in this switch is safe because
454-
/// each `rawValue` forced to casts only in exact case which is runs based on `rawValue` type
455-
// swiftlint:disable force_cast
456-
switch type(of: self.rawValue) {
457-
case is Int.Type: try enumContainer.encode(rawValue as! Int)
458-
case is [Int].Type: try enumContainer.encode(rawValue as! [Int])
459-
460-
case is UInt64.Type: try enumContainer.encode(rawValue as! UInt64)
461-
case is [UInt64].Type: try enumContainer.encode(rawValue as! [UInt64])
462-
463-
case is String.Type: try enumContainer.encode(rawValue as! String)
464-
case is [String].Type: try enumContainer.encode(rawValue as! [String])
465-
466-
case is Double.Type: try enumContainer.encode(rawValue as! Double)
467-
case is [Double].Type: try enumContainer.encode(rawValue as! [Double])
468-
469-
case is Bool.Type: try enumContainer.encode(rawValue as! Bool)
470-
case is TransactionParameters.Type: try enumContainer.encode(rawValue as! TransactionParameters)
471-
case is EventFilterParameters.Type: try enumContainer.encode(rawValue as! EventFilterParameters)
472-
default: break /// can't be executed, coz possible `self.rawValue` types are strictly defined in it's inplementation.`
473-
}
474-
// swiftlint:enable force_cast
475-
}
476-
}
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
// Package: web3swift
2+
// Created by Alex Vlasov.
3+
// Copyright © 2022 Yaroslav Yashin. All rights reserved.
4+
5+
/// Protocol to restrict supported types which can be passed into `JSONRPCRequest` to a node.
6+
///
7+
/// You **must not** conform any type to that protocol.
8+
///
9+
/// Due to internal logic and swift itself restrictions, there's lack of encoding generic types
10+
/// so current implementation of `JSONRPCParameter`s belongs on hardcoded supported types.
11+
///
12+
/// Conformance of that protocol by a custom type will be silently failed to encode (e.g. there won't be in request).
13+
///
14+
/// Please see `RPCParameter` documentation for more details.
15+
public protocol JSONRPCParameter: Encodable { }
16+
17+
protocol JSONParameterElement: Encodable { }
18+
19+
extension Int: JSONRPCParameter { }
20+
21+
extension UInt: JSONRPCParameter { }
22+
23+
// FIXME: Drop all non default types support
24+
extension UInt64: JSONRPCParameter { }
25+
26+
extension Double: JSONRPCParameter { }
27+
28+
extension String: JSONRPCParameter { }
29+
30+
extension Bool: JSONRPCParameter { }
31+
32+
extension Array: JSONRPCParameter where Element: JSONParameterElement { }
33+
34+
extension TransactionParameters: JSONRPCParameter { }
35+
36+
extension EventFilterParameters: JSONRPCParameter { }
37+
38+
extension Double: JSONParameterElement { }
39+
40+
extension Int: JSONParameterElement { }
41+
42+
// FIXME: Drop all non default types support
43+
extension UInt64: JSONParameterElement { }
44+
45+
extension String: JSONParameterElement { }
46+
47+
/**
48+
Enum to compose request to the node params.
49+
50+
In most cases request params are passed to Ethereum JSON RPC request as array of mixed type values, such as `[12,"this",true]`,
51+
thus this is not appropriate API design we have what we have.
52+
53+
Meanwhile swift don't provide strict way to compose such array it gives some hacks to solve this task
54+
and one of them is using `RawRepresentable` protocol.
55+
56+
Conforming this protocol gives designated type ability to represent itself in `String` representation in any way.
57+
58+
So in our case we're using such to implement custom `encode` method to any used in node request params types.
59+
60+
Latter is required to encode array of `RPCParameter` to not to `[RPCParameter.int(1)]`, but to `[1]`.
61+
62+
Here's an example of using this enum in field.
63+
```swift
64+
let jsonRPCParams: [JSONRPCParameter] = [
65+
.init(rawValue: 12)!,
66+
.init(rawValue: "this")!,
67+
.init(rawValue: 12.2)!,
68+
.init(rawValue: [12.2, 12.4])!
69+
]
70+
let encoded = try JSONEncoder().encode(jsonRPCParams)
71+
print(String(data: encoded, encoding: .utf8)!)
72+
//> [12,\"this\",12.2,[12.2,12.4]]`
73+
```
74+
*/
75+
public enum RPCParameter {
76+
case int(Int)
77+
case intArray([Int])
78+
79+
case uint(UInt64)
80+
case uintArray([UInt64])
81+
82+
case double(Double)
83+
case doubleArray([Double])
84+
85+
case string(String)
86+
case stringArray([String])
87+
88+
case bool(Bool)
89+
case transaction(TransactionParameters)
90+
case eventFilter(EventFilterParameters)
91+
}
92+
93+
94+
extension RPCParameter: RawRepresentable {
95+
/**
96+
This init required by `RawRepresentable` protocol, which is requred to encode mixed type values array in JSON.
97+
98+
This protocol used to implement custom `encode` method for that enum,
99+
which is encodes array of self into array of self assotiated values.
100+
101+
You're totally free to use explicit and more convenience member init as `RPCParameter.int(12)` in your code.
102+
*/
103+
public init?(rawValue: JSONRPCParameter) {
104+
/// force casting in this switch is safe because
105+
/// each `rawValue` forced to casts only in exact case which is runs based on `rawValues` type
106+
// swiftlint:disable force_cast
107+
switch type(of: rawValue) {
108+
case is Int.Type: self = .int(rawValue as! Int)
109+
case is [Int].Type: self = .intArray(rawValue as! [Int])
110+
111+
case is UInt64.Type: self = .uint(rawValue as! UInt64)
112+
case is [UInt64].Type: self = .uintArray(rawValue as! [UInt64])
113+
114+
case is String.Type: self = .string(rawValue as! String)
115+
case is [String].Type: self = .stringArray(rawValue as! [String])
116+
117+
case is Double.Type: self = .double(rawValue as! Double)
118+
case is [Double].Type: self = .doubleArray(rawValue as! [Double])
119+
120+
case is Bool.Type: self = .bool(rawValue as! Bool)
121+
case is TransactionParameters.Type: self = .transaction(rawValue as! TransactionParameters)
122+
case is EventFilterParameters.Type: self = .eventFilter(rawValue as! EventFilterParameters)
123+
default: return nil
124+
}
125+
// swiftlint:enable force_cast
126+
}
127+
128+
/// Returning associated value of the enum case.
129+
public var rawValue: JSONRPCParameter {
130+
// cases can't be merged, coz it cause compiler error since it couldn't predict what exact type on exact case will be returned.
131+
switch self {
132+
case let .int(value): return value
133+
case let .intArray(value): return value
134+
135+
case let .uint(value): return value
136+
case let .uintArray(value): return value
137+
138+
case let .string(value): return value
139+
case let .stringArray(value): return value
140+
141+
case let .double(value): return value
142+
case let .doubleArray(value): return value
143+
144+
case let .bool(value): return value
145+
case let .transaction(value): return value
146+
case let .eventFilter(value): return value
147+
}
148+
}
149+
}
150+
151+
extension RPCParameter: Encodable {
152+
/**
153+
This encoder encodes `RPCParameter` assotiated value ignoring self value
154+
155+
This is required to encode mixed types array, like
156+
157+
```swift
158+
let someArray: [RPCParameter] = [
159+
.init(rawValue: 12)!,
160+
.init(rawValue: "this")!,
161+
.init(rawValue: 12.2)!,
162+
.init(rawValue: [12.2, 12.4])!
163+
]
164+
let encoded = try JSONEncoder().encode(someArray)
165+
print(String(data: encoded, encoding: .utf8)!)
166+
//> [12,\"this\",12.2,[12.2,12.4]]`
167+
```
168+
*/
169+
public func encode(to encoder: Encoder) throws {
170+
var enumContainer = encoder.singleValueContainer()
171+
/// force casting in this switch is safe because
172+
/// each `rawValue` forced to casts only in exact case which is runs based on `rawValue` type
173+
// swiftlint:disable force_cast
174+
switch type(of: self.rawValue) {
175+
case is Int.Type: try enumContainer.encode(rawValue as! Int)
176+
case is [Int].Type: try enumContainer.encode(rawValue as! [Int])
177+
178+
case is UInt64.Type: try enumContainer.encode(rawValue as! UInt64)
179+
case is [UInt64].Type: try enumContainer.encode(rawValue as! [UInt64])
180+
181+
case is String.Type: try enumContainer.encode(rawValue as! String)
182+
case is [String].Type: try enumContainer.encode(rawValue as! [String])
183+
184+
case is Double.Type: try enumContainer.encode(rawValue as! Double)
185+
case is [Double].Type: try enumContainer.encode(rawValue as! [Double])
186+
187+
case is Bool.Type: try enumContainer.encode(rawValue as! Bool)
188+
case is TransactionParameters.Type: try enumContainer.encode(rawValue as! TransactionParameters)
189+
case is EventFilterParameters.Type: try enumContainer.encode(rawValue as! EventFilterParameters)
190+
default: break /// can't be executed, coz possible `self.rawValue` types are strictly defined in it's inplementation.`
191+
}
192+
// swiftlint:enable force_cast
193+
}
194+
}

0 commit comments

Comments
 (0)