Skip to content

Commit 3bf16a7

Browse files
authored
Merge pull request #62 from mgadda/mgadda/stricter_convenience_properties
Make `Numeric` convenience properties more strict in their type conversions
2 parents c3b5764 + 4fb2a4c commit 3bf16a7

File tree

2 files changed

+241
-17
lines changed

2 files changed

+241
-17
lines changed

Sources/MessagePack/ConvenienceProperties.swift

Lines changed: 140 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ extension MessagePackValue {
4343
}
4444
}
4545

46-
/// The integer value if `.Int` or an appropriately valued `.UInt`, `nil` otherwise.
46+
// MARK: Signed integer values
47+
48+
/// The integer value if `.int` or an appropriately valued `.uint`, `nil` otherwise.
49+
@available(*, deprecated, message: "use int64Value: instead")
4750
public var integerValue: Int64? {
4851
switch self {
4952
case .int(let value):
@@ -55,7 +58,75 @@ extension MessagePackValue {
5558
}
5659
}
5760

58-
/// The unsigned integer value if `.UInt` or positive `.Int`, `nil` otherwise.
61+
/// The signed platform-dependent width integer value if `.int` or an
62+
/// appropriately valued `.uint`, `nil` otherwise.
63+
public var intValue: Int? {
64+
switch self {
65+
case .int(let value):
66+
return Int(exactly: value)
67+
case .uint(let value):
68+
return Int(exactly: value)
69+
default:
70+
return nil
71+
}
72+
}
73+
74+
/// The signed 8-bit integer value if `.int` or an appropriately valued
75+
/// `.uint`, `nil` otherwise.
76+
public var int8Value: Int8? {
77+
switch self {
78+
case .int(let value):
79+
return Int8(exactly: value)
80+
case .uint(let value):
81+
return Int8(exactly: value)
82+
default:
83+
return nil
84+
}
85+
}
86+
87+
/// The signed 16-bit integer value if `.int` or an appropriately valued
88+
/// `.uint`, `nil` otherwise.
89+
public var int16Value: Int16? {
90+
switch self {
91+
case .int(let value):
92+
return Int16(exactly: value)
93+
case .uint(let value):
94+
return Int16(exactly: value)
95+
default:
96+
return nil
97+
}
98+
}
99+
100+
/// The signed 32-bit integer value if `.int` or an appropriately valued
101+
/// `.uint`, `nil` otherwise.
102+
public var int32Value: Int32? {
103+
switch self {
104+
case .int(let value):
105+
return Int32(exactly: value)
106+
case .uint(let value):
107+
return Int32(exactly: value)
108+
default:
109+
return nil
110+
}
111+
}
112+
113+
/// The signed 64-bit integer value if `.int` or an appropriately valued
114+
/// `.uint`, `nil` otherwise.
115+
public var int64Value: Int64? {
116+
switch self {
117+
case .int(let value):
118+
return value
119+
case .uint(let value):
120+
return Int64(exactly: value)
121+
default:
122+
return nil
123+
}
124+
}
125+
126+
// MARK: Unsigned integer values
127+
128+
/// The unsigned integer value if `.uint` or positive `.int`, `nil` otherwise.
129+
@available(*, deprecated, message: "use uint64Value: instead")
59130
public var unsignedIntegerValue: UInt64? {
60131
switch self {
61132
case .int(let value) where value >= 0:
@@ -67,6 +138,71 @@ extension MessagePackValue {
67138
}
68139
}
69140

141+
/// The unsigned platform-dependent width integer value if `.uint` or an
142+
/// appropriately valued `.int`, `nil` otherwise.
143+
public var uintValue: UInt? {
144+
switch self {
145+
case .int(let value):
146+
return UInt(exactly: value)
147+
case .uint(let value):
148+
return UInt(exactly: value)
149+
default:
150+
return nil
151+
}
152+
}
153+
154+
/// The unsigned 8-bit integer value if `.uint` or an appropriately valued
155+
/// `.int`, `nil` otherwise.
156+
public var uint8Value: UInt8? {
157+
switch self {
158+
case .int(let value):
159+
return UInt8(exactly: value)
160+
case .uint(let value):
161+
return UInt8(exactly: value)
162+
default:
163+
return nil
164+
}
165+
}
166+
167+
/// The unsigned 16-bit integer value if `.uint` or an appropriately valued
168+
/// `.int`, `nil` otherwise.
169+
public var uint16Value: UInt16? {
170+
switch self {
171+
case .int(let value):
172+
return UInt16(exactly: value)
173+
case .uint(let value):
174+
return UInt16(exactly: value)
175+
default:
176+
return nil
177+
}
178+
}
179+
180+
/// The unsigned 32-bit integer value if `.uint` or an appropriately valued
181+
/// `.int`, `nil` otherwise.
182+
public var uint32Value: UInt32? {
183+
switch self {
184+
case .int(let value):
185+
return UInt32(exactly: value)
186+
case .uint(let value):
187+
return UInt32(exactly: value)
188+
default:
189+
return nil
190+
}
191+
}
192+
193+
/// The unsigned 64-bit integer value if `.uint` or an appropriately valued
194+
/// `.int`, `nil` otherwise.
195+
public var uint64Value: UInt64? {
196+
switch self {
197+
case .int(let value):
198+
return UInt64(exactly: value)
199+
case .uint(let value):
200+
return value
201+
default:
202+
return nil
203+
}
204+
}
205+
70206
/// The contained array if `.Array`, `nil` otherwise.
71207
public var arrayValue: [MessagePackValue]? {
72208
switch self {
@@ -93,7 +229,7 @@ extension MessagePackValue {
93229
case .float(let value):
94230
return value
95231
case .double(let value):
96-
return Float(value)
232+
return Float(exactly: value)
97233
default:
98234
return nil
99235
}
@@ -103,7 +239,7 @@ extension MessagePackValue {
103239
public var doubleValue: Double? {
104240
switch self {
105241
case .float(let value):
106-
return Double(value)
242+
return Double(exactly: value)
107243
case .double(let value):
108244
return value
109245
default:

Tests/MessagePackTests/ConveniencePropertiesTests.swift

Lines changed: 101 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,16 @@ class ConveniencePropertiesTests: XCTestCase {
99
("testIndexedSubscript", testIndexedSubscript),
1010
("testKeyedSubscript", testKeyedSubscript),
1111
("testIsNil", testIsNil),
12-
("testIntegerValue", testIntegerValue),
13-
("testUnsignedIntegerValue", testUnsignedIntegerValue),
12+
("testIntValue", testIntValue),
13+
("testInt8Value", testInt8Value),
14+
("testInt16Value", testInt16Value),
15+
("testIn32Value", testInt32Value),
16+
("testInt64Value", testInt64Value),
17+
("testUIntValue", testUIntValue),
18+
("testUInt8Value", testUInt8Value),
19+
("testUInt16Value", testUInt16Value),
20+
("testUInt32Value", testUInt32Value),
21+
("testUInt64Value", testUInt64Value),
1422
("testArrayValue", testArrayValue),
1523
("testBoolValue", testBoolValue),
1624
("testFloatValue", testFloatValue),
@@ -46,17 +54,98 @@ class ConveniencePropertiesTests: XCTestCase {
4654
XCTAssertFalse(MessagePackValue.bool(true).isNil)
4755
}
4856

49-
func testIntegerValue() {
50-
XCTAssert(MessagePackValue.int(-1).integerValue == -1)
51-
XCTAssert(MessagePackValue.uint(1).integerValue == 1)
52-
XCTAssert(MessagePackValue.nil.integerValue == nil)
57+
func testIntValue() {
58+
XCTAssert(MessagePackValue.int(-1).intValue == -1)
59+
XCTAssert(MessagePackValue.uint(1).intValue == 1)
60+
XCTAssertNil(MessagePackValue.nil.intValue)
5361
}
5462

55-
func testUnsignedIntegerValue() {
56-
XCTAssert(MessagePackValue.int(-1).unsignedIntegerValue == nil)
57-
XCTAssert(MessagePackValue.int(1).unsignedIntegerValue == 1)
58-
XCTAssert(MessagePackValue.uint(1).unsignedIntegerValue == 1)
59-
XCTAssert(MessagePackValue.nil.unsignedIntegerValue == nil)
63+
func testInt8Value() {
64+
XCTAssert(MessagePackValue.int(-1).int8Value == -1)
65+
XCTAssert(MessagePackValue.int(1).int8Value == 1)
66+
XCTAssertNil(MessagePackValue.int(Int64(Int8.min) - 1).int8Value)
67+
XCTAssertNil(MessagePackValue.int(Int64(Int8.max) + 1).int8Value)
68+
69+
XCTAssert(MessagePackValue.uint(1).int8Value == 1)
70+
XCTAssertNil(MessagePackValue.uint(UInt64(Int8.max) + 1).int8Value)
71+
XCTAssertNil(MessagePackValue.nil.int8Value)
72+
}
73+
74+
func testInt16Value() {
75+
XCTAssert(MessagePackValue.int(-1).int16Value == -1)
76+
XCTAssert(MessagePackValue.int(1).int16Value == 1)
77+
XCTAssertNil(MessagePackValue.int(Int64(Int16.min) - 1).int16Value)
78+
XCTAssertNil(MessagePackValue.int(Int64(Int16.max) + 1).int16Value)
79+
80+
XCTAssert(MessagePackValue.uint(1).int16Value == 1)
81+
XCTAssertNil(MessagePackValue.uint(UInt64(Int16.max) + 1).int16Value)
82+
XCTAssertNil(MessagePackValue.nil.int16Value)
83+
}
84+
85+
func testInt32Value() {
86+
XCTAssert(MessagePackValue.int(-1).int32Value == -1)
87+
XCTAssert(MessagePackValue.int(1).int32Value == 1)
88+
XCTAssertNil(MessagePackValue.int(Int64(Int32.min) - 1).int32Value)
89+
XCTAssertNil(MessagePackValue.int(Int64(Int32.max) + 1).int32Value)
90+
91+
XCTAssert(MessagePackValue.uint(1).int32Value == 1)
92+
XCTAssertNil(MessagePackValue.uint(UInt64(Int32.max) + 1).int32Value)
93+
XCTAssertNil(MessagePackValue.nil.int32Value)
94+
}
95+
96+
func testInt64Value() {
97+
XCTAssert(MessagePackValue.int(-1).int64Value == -1)
98+
XCTAssert(MessagePackValue.int(1).int64Value == 1)
99+
100+
XCTAssert(MessagePackValue.uint(1).int64Value == 1)
101+
XCTAssertNil(MessagePackValue.uint(UInt64(Int64.max) + 1).int64Value)
102+
XCTAssertNil(MessagePackValue.nil.int64Value)
103+
}
104+
105+
func testUIntValue() {
106+
XCTAssert(MessagePackValue.uint(1).uintValue == 1)
107+
108+
XCTAssertNil(MessagePackValue.int(-1).uintValue)
109+
XCTAssert(MessagePackValue.int(1).uintValue == 1)
110+
XCTAssertNil(MessagePackValue.nil.uintValue)
111+
}
112+
113+
func testUInt8Value() {
114+
XCTAssert(MessagePackValue.uint(1).uint8Value == 1)
115+
XCTAssertNil(MessagePackValue.uint(UInt64(UInt8.max) + 1).uint8Value)
116+
117+
XCTAssertNil(MessagePackValue.int(-1).uint8Value)
118+
XCTAssert(MessagePackValue.int(1).uint8Value == 1)
119+
XCTAssertNil(MessagePackValue.int(Int64(UInt8.max) + 1).uint8Value)
120+
XCTAssertNil(MessagePackValue.nil.uint8Value)
121+
}
122+
123+
func testUInt16Value() {
124+
XCTAssert(MessagePackValue.uint(1).uint16Value == 1)
125+
XCTAssertNil(MessagePackValue.uint(UInt64(UInt16.max) + 1).uint16Value)
126+
127+
XCTAssertNil(MessagePackValue.int(-1).uint16Value)
128+
XCTAssert(MessagePackValue.int(1).uint16Value == 1)
129+
XCTAssertNil(MessagePackValue.int(Int64(UInt16.max) + 1).uint16Value)
130+
XCTAssertNil(MessagePackValue.nil.uint16Value)
131+
}
132+
133+
func testUInt32Value() {
134+
XCTAssert(MessagePackValue.uint(1).uint32Value == 1)
135+
XCTAssertNil(MessagePackValue.uint(UInt64(UInt32.max) + 1).uint32Value)
136+
137+
XCTAssertNil(MessagePackValue.int(-1).uint32Value)
138+
XCTAssert(MessagePackValue.int(1).uint32Value == 1)
139+
XCTAssertNil(MessagePackValue.int(Int64(UInt32.max) + 1).uint32Value)
140+
XCTAssertNil(MessagePackValue.nil.uint32Value)
141+
}
142+
143+
func testUInt64Value() {
144+
XCTAssert(MessagePackValue.uint(1).uint64Value == 1)
145+
146+
XCTAssertNil(MessagePackValue.int(-1).uint64Value)
147+
XCTAssert(MessagePackValue.int(1).uint64Value == 1)
148+
XCTAssertNil(MessagePackValue.nil.uint8Value)
60149
}
61150

62151
func testArrayValue() {
@@ -80,8 +169,7 @@ class ConveniencePropertiesTests: XCTestCase {
80169
XCTAssertEqual(floatValue!, 3.14, accuracy: 0.0001)
81170

82171
floatValue = MessagePackValue.double(3.14).floatValue
83-
XCTAssertNotNil(floatValue)
84-
XCTAssertEqual(floatValue!, 3.14, accuracy: 0.0001)
172+
XCTAssertNil(floatValue)
85173
}
86174

87175
func testDoubleValue() {

0 commit comments

Comments
 (0)