Skip to content

Commit c889293

Browse files
committed
Add applying and tests
1 parent d36b824 commit c889293

File tree

2 files changed

+385
-0
lines changed

2 files changed

+385
-0
lines changed
Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
//
2+
// Sources/SwiftProtobuf/Applying.swift - Applying protocol and errors
3+
//
4+
// Copyright (c) 2023 Apple Inc. and the project authors
5+
// Licensed under Apache License v2.0 with Runtime Library Exception
6+
//
7+
// See LICENSE.txt for license information:
8+
// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt
9+
//
10+
// -----------------------------------------------------------------------------
11+
///
12+
/// Applying feature (including decoder and errors)
13+
///
14+
// -----------------------------------------------------------------------------
15+
16+
import Foundation
17+
18+
/// Describes errors can occure during applying a value to proto
19+
public enum ProtoApplyingError: Error {
20+
21+
/// Describes a mismatch in type of the field
22+
///
23+
/// If a value of type A is applied to a fieldNumber with type B
24+
/// this error will be thrown by the applying() method.
25+
case typeMismatch
26+
}
27+
28+
internal struct ApplyingDecoder: Decoder {
29+
30+
private var _fieldNumber: Int?
31+
private var _value: Any
32+
33+
init(fieldNumber: Int, value: Any) {
34+
self._fieldNumber = fieldNumber
35+
self._value = value
36+
}
37+
38+
mutating func handleConflictingOneOf() throws {}
39+
40+
mutating func nextFieldNumber() throws -> Int? {
41+
if let fieldNumber = _fieldNumber {
42+
_fieldNumber = nil
43+
return fieldNumber
44+
}
45+
return nil
46+
}
47+
48+
private func _value<T>(as type: T.Type) throws -> T {
49+
guard let __value = _value as? T else {
50+
throw ProtoApplyingError.typeMismatch
51+
}
52+
return __value
53+
}
54+
55+
mutating func decodeSingularFloatField(value: inout Float) throws {
56+
value = try _value(as: Float.self)
57+
}
58+
59+
mutating func decodeSingularFloatField(value: inout Float?) throws {
60+
value = try _value(as: Float?.self)
61+
}
62+
63+
mutating func decodeRepeatedFloatField(value: inout [Float]) throws {
64+
value = try _value(as: [Float].self)
65+
}
66+
67+
mutating func decodeSingularDoubleField(value: inout Double) throws {
68+
value = try _value(as: Double.self)
69+
}
70+
71+
mutating func decodeSingularDoubleField(value: inout Double?) throws {
72+
value = try _value(as: Double?.self)
73+
}
74+
75+
mutating func decodeRepeatedDoubleField(value: inout [Double]) throws {
76+
value = try _value(as: [Double].self)
77+
}
78+
79+
mutating func decodeSingularInt32Field(value: inout Int32) throws {
80+
value = try _value(as: Int32.self)
81+
}
82+
83+
mutating func decodeSingularInt32Field(value: inout Int32?) throws {
84+
value = try _value(as: Int32?.self)
85+
}
86+
87+
mutating func decodeRepeatedInt32Field(value: inout [Int32]) throws {
88+
value = try _value(as: [Int32].self)
89+
}
90+
91+
mutating func decodeSingularInt64Field(value: inout Int64) throws {
92+
value = try _value(as: Int64.self)
93+
}
94+
95+
mutating func decodeSingularInt64Field(value: inout Int64?) throws {
96+
value = try _value(as: Int64?.self)
97+
}
98+
99+
mutating func decodeRepeatedInt64Field(value: inout [Int64]) throws {
100+
value = try _value(as: [Int64].self)
101+
}
102+
103+
mutating func decodeSingularUInt32Field(value: inout UInt32) throws {
104+
value = try _value(as: UInt32.self)
105+
}
106+
107+
mutating func decodeSingularUInt32Field(value: inout UInt32?) throws {
108+
value = try _value(as: UInt32?.self)
109+
}
110+
111+
mutating func decodeRepeatedUInt32Field(value: inout [UInt32]) throws {
112+
value = try _value(as: [UInt32].self)
113+
}
114+
115+
mutating func decodeSingularUInt64Field(value: inout UInt64) throws {
116+
value = try _value(as: UInt64.self)
117+
}
118+
119+
mutating func decodeSingularUInt64Field(value: inout UInt64?) throws {
120+
value = try _value(as: UInt64?.self)
121+
}
122+
123+
mutating func decodeRepeatedUInt64Field(value: inout [UInt64]) throws {
124+
value = try _value(as: [UInt64].self)
125+
}
126+
127+
mutating func decodeSingularSInt32Field(value: inout Int32) throws {
128+
value = try _value(as: Int32.self)
129+
}
130+
131+
mutating func decodeSingularSInt32Field(value: inout Int32?) throws {
132+
value = try _value(as: Int32?.self)
133+
}
134+
135+
mutating func decodeRepeatedSInt32Field(value: inout [Int32]) throws {
136+
value = try _value(as: [Int32].self)
137+
}
138+
139+
mutating func decodeSingularSInt64Field(value: inout Int64) throws {
140+
value = try _value(as: Int64.self)
141+
}
142+
143+
mutating func decodeSingularSInt64Field(value: inout Int64?) throws {
144+
value = try _value(as: Int64?.self)
145+
}
146+
147+
mutating func decodeRepeatedSInt64Field(value: inout [Int64]) throws {
148+
value = try _value(as: [Int64].self)
149+
}
150+
151+
mutating func decodeSingularFixed32Field(value: inout UInt32) throws {
152+
value = try _value(as: UInt32.self)
153+
}
154+
155+
mutating func decodeSingularFixed32Field(value: inout UInt32?) throws {
156+
value = try _value(as: UInt32?.self)
157+
}
158+
159+
mutating func decodeRepeatedFixed32Field(value: inout [UInt32]) throws {
160+
value = try _value(as: [UInt32].self)
161+
}
162+
163+
mutating func decodeSingularFixed64Field(value: inout UInt64) throws {
164+
value = try _value(as: UInt64.self)
165+
}
166+
167+
mutating func decodeSingularFixed64Field(value: inout UInt64?) throws {
168+
value = try _value(as: UInt64?.self)
169+
}
170+
171+
mutating func decodeRepeatedFixed64Field(value: inout [UInt64]) throws {
172+
value = try _value(as: [UInt64].self)
173+
}
174+
175+
mutating func decodeSingularSFixed32Field(value: inout Int32) throws {
176+
value = try _value(as: Int32.self)
177+
}
178+
179+
mutating func decodeSingularSFixed32Field(value: inout Int32?) throws {
180+
value = try _value(as: Int32?.self)
181+
}
182+
183+
mutating func decodeRepeatedSFixed32Field(value: inout [Int32]) throws {
184+
value = try _value(as: [Int32].self)
185+
}
186+
187+
mutating func decodeSingularSFixed64Field(value: inout Int64) throws {
188+
value = try _value(as: Int64.self)
189+
}
190+
191+
mutating func decodeSingularSFixed64Field(value: inout Int64?) throws {
192+
value = try _value(as: Int64?.self)
193+
}
194+
195+
mutating func decodeRepeatedSFixed64Field(value: inout [Int64]) throws {
196+
value = try _value(as: [Int64].self)
197+
}
198+
199+
mutating func decodeSingularBoolField(value: inout Bool) throws {
200+
value = try _value(as: Bool.self)
201+
}
202+
203+
mutating func decodeSingularBoolField(value: inout Bool?) throws {
204+
value = try _value(as: Bool?.self)
205+
}
206+
207+
mutating func decodeRepeatedBoolField(value: inout [Bool]) throws {
208+
value = try _value(as: [Bool].self)
209+
}
210+
211+
mutating func decodeSingularStringField(value: inout String) throws {
212+
value = try _value(as: String.self)
213+
}
214+
215+
mutating func decodeSingularStringField(value: inout String?) throws {
216+
value = try _value(as: String?.self)
217+
}
218+
219+
mutating func decodeRepeatedStringField(value: inout [String]) throws {
220+
value = try _value(as: [String].self)
221+
}
222+
223+
mutating func decodeSingularBytesField(value: inout Data) throws {
224+
value = try _value(as: Data.self)
225+
}
226+
227+
mutating func decodeSingularBytesField(value: inout Data?) throws {
228+
value = try _value(as: Data?.self)
229+
}
230+
231+
mutating func decodeRepeatedBytesField(value: inout [Data]) throws {
232+
value = try _value(as: [Data].self)
233+
}
234+
235+
mutating func decodeSingularEnumField<E>(value: inout E) throws {
236+
value = try _value(as: E.self)
237+
}
238+
239+
mutating func decodeSingularEnumField<E>(value: inout E?) throws {
240+
value = try _value(as: E?.self)
241+
}
242+
243+
mutating func decodeRepeatedEnumField<E>(value: inout [E]) throws {
244+
value = try _value(as: [E].self)
245+
}
246+
247+
mutating func decodeSingularMessageField<M>(value: inout M?) throws {
248+
value = try _value(as: M?.self)
249+
}
250+
251+
mutating func decodeRepeatedMessageField<M>(value: inout [M]) throws {
252+
value = try _value(as: [M].self)
253+
}
254+
255+
mutating func decodeSingularGroupField<G>(value: inout G?) throws {
256+
value = try _value(as: G?.self)
257+
}
258+
259+
mutating func decodeRepeatedGroupField<G>(value: inout [G]) throws {
260+
value = try _value(as: [G].self)
261+
}
262+
263+
mutating func decodeMapField<KeyType, ValueType>(
264+
fieldType: _ProtobufMap<KeyType, ValueType>.Type,
265+
value: inout _ProtobufMap<KeyType, ValueType>.BaseType
266+
) throws {
267+
value = try _value(as: _ProtobufMap<KeyType, ValueType>.BaseType.self)
268+
}
269+
270+
mutating func decodeMapField<KeyType, ValueType>(
271+
fieldType: _ProtobufEnumMap<KeyType, ValueType>.Type,
272+
value: inout _ProtobufEnumMap<KeyType, ValueType>.BaseType
273+
) throws {
274+
value = try _value(as: _ProtobufEnumMap<KeyType, ValueType>.BaseType.self)
275+
}
276+
277+
mutating func decodeMapField<KeyType, ValueType>(
278+
fieldType: _ProtobufMessageMap<KeyType, ValueType>.Type,
279+
value: inout _ProtobufMessageMap<KeyType, ValueType>.BaseType
280+
) throws {
281+
value = try _value(as: _ProtobufMessageMap<KeyType, ValueType>.BaseType.self)
282+
}
283+
284+
mutating func decodeExtensionField(
285+
values: inout ExtensionFieldValueSet,
286+
messageType: Message.Type,
287+
fieldNumber: Int
288+
) throws {
289+
try values.modify(index: fieldNumber) { ext in
290+
try ext?.decodeExtensionField(decoder: &self)
291+
}
292+
}
293+
294+
}
295+
296+
public extension Message {
297+
func applying(_ value: Any, for fieldNumber: Int) throws -> Self {
298+
var copy = self
299+
try copy.apply(value, for: fieldNumber)
300+
return copy
301+
}
302+
303+
mutating func apply(_ value: Any, for fieldNumber: Int) throws {
304+
var decoder = ApplyingDecoder(fieldNumber: fieldNumber, value: value)
305+
try decodeMessage(decoder: &decoder)
306+
}
307+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Tests/SwiftProtobufTests/Test_Applying.swift - Applying method
2+
//
3+
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
4+
// Licensed under Apache License v2.0 with Runtime Library Exception
5+
//
6+
// See LICENSE.txt for license information:
7+
// https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt
8+
//
9+
// -----------------------------------------------------------------------------
10+
11+
import Foundation
12+
import XCTest
13+
import SwiftProtobuf
14+
15+
final class Test_Applying: XCTestCase {
16+
17+
func testApplying() throws {
18+
let message = SwiftProtoTesting_TestAny()
19+
let newMessage = try message.applying(Int32(2), for: 1)
20+
XCTAssertEqual(newMessage.int32Value, 2)
21+
}
22+
23+
func testApply() throws {
24+
var message = SwiftProtoTesting_TestAny()
25+
try message.apply(Int32(2), for: 1)
26+
XCTAssertEqual(message.int32Value, 2)
27+
}
28+
29+
func testApplyingSequentially() throws {
30+
let message = SwiftProtoTesting_TestAny()
31+
let newMessage = try message
32+
.applying(Int32(2), for: 1)
33+
.applying("test", for: 4)
34+
XCTAssertEqual(newMessage.int32Value, 2)
35+
XCTAssertEqual(newMessage.text, "test")
36+
}
37+
38+
func testApplyingMismatchType() throws {
39+
let message = SwiftProtoTesting_TestAny()
40+
XCTAssertThrowsError(try message.applying("", for: 1))
41+
}
42+
43+
func testApplyMismatchType() throws {
44+
var message = SwiftProtoTesting_TestAny()
45+
XCTAssertThrowsError(try message.apply("", for: 1))
46+
}
47+
48+
func testApplyingOneof() throws {
49+
let message = SwiftProtoTesting_TestOneof.with { oneof in
50+
oneof.foo = .fooInt(1)
51+
}
52+
let newMessage = try message.applying("oneof", for: 2)
53+
XCTAssertEqual(newMessage.foo, .fooString("oneof"))
54+
}
55+
56+
func testApplyOneof() throws {
57+
var message = SwiftProtoTesting_TestOneof.with { oneof in
58+
oneof.foo = .fooInt(1)
59+
}
60+
try message.apply("oneof", for: 2)
61+
XCTAssertEqual(message.foo, .fooString("oneof"))
62+
}
63+
64+
func testApplyingExtension() throws {
65+
var message = SwiftProtoTesting_Extend_Msg1()
66+
message.SwiftProtoTesting_Extend_aB = 0
67+
let newMessage = try message.applying(Int32(2), for: 1)
68+
XCTAssertEqual(newMessage.SwiftProtoTesting_Extend_aB, 2)
69+
}
70+
71+
func testApplyExtension() throws {
72+
var message = SwiftProtoTesting_Extend_Msg1()
73+
message.SwiftProtoTesting_Extend_aB = 0
74+
try message.apply(Int32(2), for: 1)
75+
XCTAssertEqual(message.SwiftProtoTesting_Extend_aB, 2)
76+
}
77+
78+
}

0 commit comments

Comments
 (0)