Skip to content

Commit 4df321e

Browse files
committed
Made all numeric types support protocol Codable.
1 parent ebb6c28 commit 4df321e

File tree

14 files changed

+133
-18
lines changed

14 files changed

+133
-18
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 2.3.3 (2020-02-09)
4+
- Made all numeric types support protocol `Codable`
5+
- Migrated project to Xcode 11.3
6+
37
## 2.3.2 (2019-10-20)
48
- Migrated project to Xcode 11.1
59
- Removed non-shared scheme from project

NumberKit.xcodeproj/project.pbxproj

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
CC99F56C1B7AA81500355E1E /* BigInt.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC99F56B1B7AA81500355E1E /* BigInt.swift */; };
1818
CC99F56E1B7AAAA300355E1E /* NumberUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC99F56D1B7AAAA300355E1E /* NumberUtil.swift */; };
1919
CC99F5701B7AAB5300355E1E /* NumberUtilTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC99F56F1B7AAB5300355E1E /* NumberUtilTests.swift */; };
20+
CCA2651723EF73B700483329 /* CodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCA2651623EF73B700483329 /* CodableTests.swift */; };
2021
CCA8E8111F7780C800927A41 /* FloatingPointNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCA8E8101F7780C800927A41 /* FloatingPointNumber.swift */; };
2122
CCA8E8131F77814F00927A41 /* IntegerNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCA8E8121F77814F00927A41 /* IntegerNumber.swift */; };
2223
/* End PBXBuildFile section */
@@ -48,6 +49,7 @@
4849
CC99F56F1B7AAB5300355E1E /* NumberUtilTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumberUtilTests.swift; sourceTree = "<group>"; };
4950
CC99F5711B7AB5E600355E1E /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
5051
CC99F5721B7AB66E00355E1E /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
52+
CCA2651623EF73B700483329 /* CodableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodableTests.swift; sourceTree = "<group>"; };
5153
CCA8E8101F7780C800927A41 /* FloatingPointNumber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FloatingPointNumber.swift; sourceTree = "<group>"; };
5254
CCA8E8121F77814F00927A41 /* IntegerNumber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntegerNumber.swift; sourceTree = "<group>"; };
5355
CCB691501EB7710700B32D55 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = "<group>"; };
@@ -122,6 +124,7 @@
122124
CC99F5691B7AA76600355E1E /* BigIntTests.swift */,
123125
CC07415A1B813A0600406A43 /* RationalTests.swift */,
124126
CC07415C1B813B0300406A43 /* ComplexTests.swift */,
127+
CCA2651623EF73B700483329 /* CodableTests.swift */,
125128
CC5E473320C428D500F21B03 /* LinuxMain.swift */,
126129
CC99F5601B7AA6E200355E1E /* Info.plist */,
127130
);
@@ -255,6 +258,7 @@
255258
isa = PBXSourcesBuildPhase;
256259
buildActionMask = 2147483647;
257260
files = (
261+
CCA2651723EF73B700483329 /* CodableTests.swift in Sources */,
258262
CC07415D1B813B0300406A43 /* ComplexTests.swift in Sources */,
259263
CC99F5701B7AAB5300355E1E /* NumberUtilTests.swift in Sources */,
260264
CC99F56A1B7AA76600355E1E /* BigIntTests.swift in Sources */,
@@ -397,7 +401,7 @@
397401
INFOPLIST_FILE = "$(SRCROOT)/Sources/NumberKit/Info.plist";
398402
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
399403
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
400-
MARKETING_VERSION = 2.3.2;
404+
MARKETING_VERSION = 2.3.3;
401405
PRODUCT_BUNDLE_IDENTIFIER = net.objecthub.NumberKit;
402406
PRODUCT_NAME = "$(TARGET_NAME)";
403407
SKIP_INSTALL = YES;
@@ -419,7 +423,7 @@
419423
INFOPLIST_FILE = "$(SRCROOT)/Sources/NumberKit/Info.plist";
420424
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
421425
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
422-
MARKETING_VERSION = 2.3.2;
426+
MARKETING_VERSION = 2.3.3;
423427
PRODUCT_BUNDLE_IDENTIFIER = net.objecthub.NumberKit;
424428
PRODUCT_NAME = "$(TARGET_NAME)";
425429
SKIP_INSTALL = YES;

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
<p>
44
<a href="https://developer.apple.com/osx/"><img src="https://img.shields.io/badge/Platform-macOS-blue.svg?style=flat" alt="Platform: macOS" /></a>
55
<a href="https://developer.apple.com/swift/"><img src="https://img.shields.io/badge/Language-Swift%205.1-green.svg?style=flat" alt="Language: Swift 5.1" /></a>
6-
<a href="https://developer.apple.com/xcode/"><img src="https://img.shields.io/badge/IDE-Xcode%2011.1-orange.svg?style=flat" alt="IDE: Xcode 11.1" /></a>
6+
<a href="https://developer.apple.com/xcode/"><img src="https://img.shields.io/badge/IDE-Xcode%2011.3-orange.svg?style=flat" alt="IDE: Xcode 11.3" /></a>
77
<a href="https://raw.githubusercontent.com/objecthub/swift-lispkit/master/LICENSE"><img src="http://img.shields.io/badge/License-Apache-lightgrey.svg?style=flat" alt="License: Apache" /></a>
88
</p>
99

10+
1011
## Overview
1112

1213
This is a framework implementing advanced numeric data types for the Swift programming
@@ -17,7 +18,7 @@ language. Currently, the framework provides three new numeric types, each repres
1718
3. `Complex`: complex floating-point numbers
1819

1920
**Requirements**:
20-
- Xcode 11.1
21+
- Xcode 11.3
2122
- Swift 5.1
2223
- macOS with Xcode or Swift Package Manager
2324
- Linux with Swift Package Manager

Sources/NumberKit/BigInt.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,16 @@ import Foundation
3333
/// representing a `UInt64` value as a `BigInt` will result in an object that
3434
/// requires more memory than the corresponding `UInt64` integer.
3535
public struct BigInt: Hashable,
36+
Codable,
3637
CustomStringConvertible,
3738
CustomDebugStringConvertible {
3839

40+
// Redefine the coding key names.
41+
enum CodingKeys: String, CodingKey {
42+
case uwords = "words"
43+
case negative
44+
}
45+
3946
// This is an array of `UInt32` words. The lowest significant word comes first in
4047
// the array.
4148
private let uwords: ContiguousArray<UInt32>

Sources/NumberKit/Complex.swift

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,10 @@ public protocol ComplexNumber: Equatable {
122122
/// implement a complex number as it does not define interfaces for trigonometric
123123
/// functions.
124124
public struct Complex<T: FloatingPointNumber>: ComplexNumber,
125-
Hashable,
126-
ExpressibleByIntegerLiteral,
127-
ExpressibleByFloatLiteral,
128-
CustomStringConvertible {
125+
Hashable,
126+
ExpressibleByIntegerLiteral,
127+
ExpressibleByFloatLiteral,
128+
CustomStringConvertible {
129129

130130
/// The real part of thix complex number.
131131
public let re: T
@@ -569,3 +569,13 @@ public func atanh<C: ComplexNumber>(_ z: C) -> C {
569569
return log(x.divided(by: y)).divided(by: C.Float(2))
570570
}
571571

572+
/// This extension implements the logic to make `Complex<T>` codable if `T` is codable.
573+
extension Complex: Codable where T: Codable {
574+
575+
// Make coding key names explicit to avoid automatic extension.
576+
enum CodingKeys: String, CodingKey {
577+
case re = "real"
578+
case im = "imaginary"
579+
}
580+
581+
}

Sources/NumberKit/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<key>CFBundleVersion</key>
2222
<string>$(CURRENT_PROJECT_VERSION)</string>
2323
<key>NSHumanReadableCopyright</key>
24-
<string>Copyright © 2015–2019 Matthias Zenger. All rights reserved.</string>
24+
<string>Copyright © 2015–2020 Matthias Zenger. All rights reserved.</string>
2525
<key>NSPrincipalClass</key>
2626
<string></string>
2727
</dict>

Sources/NumberKit/Rational.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,5 +559,16 @@ public func != <R: RationalNumber>(lhs: R, rhs: R) -> Bool {
559559
return lhs.compare(to: rhs) != 0
560560
}
561561

562+
/// This extension implements the logic to make `Rational<T>` codable if `T` is codable.
563+
extension Rational: Codable where T: Codable {
564+
565+
// Make coding key names explicit to avoid automatic extension.
566+
enum CodingKeys: String, CodingKey {
567+
case numerator
568+
case denominator
569+
}
570+
571+
}
572+
562573
// TODO: make this a static member of `Rational` once this is supported
563574
private let rationalSeparator: Character = "/"

Tests/LinuxMain.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ XCTMain(
99
testCase(ComplexTests.allTests),
1010
testCase(RationalTests.allTests),
1111
testCase(NumberUtilTests.allTests),
12+
testCase(CodableTests.allTests),
1213
]
1314
)
1415

Tests/NumberKitTests/BigIntTests.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// NumberKit
44
//
55
// Created by Matthias Zenger on 11/08/2015.
6-
// Copyright © 2015-2019 Matthias Zenger. All rights reserved.
6+
// Copyright © 2015-2020 Matthias Zenger. All rights reserved.
77
//
88
// Licensed under the Apache License, Version 2.0 (the "License");
99
// you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@
2121
import XCTest
2222
@testable import NumberKit
2323

24-
2524
class BigIntTests: XCTestCase {
2625

2726
func testConstructors() {
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//
2+
// CodableTests.swift
3+
// NumberKitTests
4+
//
5+
// Created by Matthias Zenger on 08/02/2020.
6+
// Copyright © 2020 Matthias Zenger. All rights reserved.
7+
//
8+
// Licensed under the Apache License, Version 2.0 (the "License");
9+
// you may not use this file except in compliance with the License.
10+
// You may obtain a copy of the License at
11+
//
12+
// http://www.apache.org/licenses/LICENSE-2.0
13+
//
14+
// Unless required by applicable law or agreed to in writing, software
15+
// distributed under the License is distributed on an "AS IS" BASIS,
16+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
// See the License for the specific language governing permissions and
18+
// limitations under the License.
19+
//
20+
21+
import XCTest
22+
@testable import NumberKit
23+
24+
class CodableTests: XCTestCase {
25+
26+
func testComplexCodable() {
27+
let c1: Complex<Double> = 987654.41 - 2.0.i
28+
XCTAssertEqual(self.recodeJSON(c1), c1)
29+
let c2: Complex<Double> = 1.5.i
30+
XCTAssertEqual(self.recodeJSON(c2), c2)
31+
let c3: Complex<Double> = 0.0
32+
XCTAssertEqual(self.recodeJSON(c3), c3)
33+
}
34+
35+
func testRationalCodable() {
36+
let r1: Rational<Int> = 7/2
37+
XCTAssertEqual(self.recodeJSON(r1), r1)
38+
let r2: Rational<Int> = 7654321
39+
XCTAssertEqual(self.recodeJSON(r2), r2)
40+
let r3: Rational<Int> = 0
41+
XCTAssertEqual(self.recodeJSON(r3), r3)
42+
}
43+
44+
func testBigIntCodable() {
45+
let x1: BigInt = "811248574598402980294572048572242498127"
46+
XCTAssertEqual(self.recodeJSON(x1), x1)
47+
let x2: BigInt = "847597200"
48+
XCTAssertEqual(self.recodeJSON(x2), x2)
49+
let x3: BigInt = "-75537574353998534693615828134454330968785329792741330257228043492082567"
50+
XCTAssertEqual(self.recodeJSON(x3), x3)
51+
}
52+
53+
private func recodeJSON<T: Codable>(_ obj: T) -> T? {
54+
guard let encodedObj = self.encodeJSON(obj) else {
55+
return nil
56+
}
57+
return self.decodeJSON(type(of: obj), encodedObj)
58+
}
59+
60+
private func encodeJSON<T: Codable>(_ obj: T) -> String? {
61+
guard let encodedObj = try? JSONEncoder().encode(obj) else {
62+
return nil
63+
}
64+
guard let res = String(data: encodedObj, encoding: .utf8) else {
65+
return nil
66+
}
67+
return res
68+
}
69+
70+
private func decodeJSON<T: Codable>(_ type: T.Type, _ str: String) -> T? {
71+
return try? JSONDecoder().decode(type, from: str.data(using: .utf8)!)
72+
}
73+
74+
static let allTests = [
75+
("testComplexCodable", testComplexCodable),
76+
("testRationalCodable", testRationalCodable),
77+
("testBigIntCodable", testBigIntCodable),
78+
]
79+
}

Tests/NumberKitTests/ComplexTests.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// NumberKit
44
//
55
// Created by Matthias Zenger on 16/08/2015.
6-
// Copyright © 2015-2019 Matthias Zenger. All rights reserved.
6+
// Copyright © 2015-2020 Matthias Zenger. All rights reserved.
77
//
88
// Licensed under the Apache License, Version 2.0 (the "License");
99
// you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@
2121
import XCTest
2222
@testable import NumberKit
2323

24-
2524
class ComplexTests: XCTestCase {
2625

2726
func testConstructors() {

Tests/NumberKitTests/Info.plist

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
<key>CFBundlePackageType</key>
1616
<string>BNDL</string>
1717
<key>CFBundleShortVersionString</key>
18-
<string>2.3.2</string>
18+
<string>2.3.3</string>
1919
<key>CFBundleSignature</key>
2020
<string>????</string>
2121
<key>CFBundleVersion</key>
2222
<string>1</string>
23+
<key>NSHumanReadableCopyright</key>
24+
<string>Copyright © 2015–2020 Matthias Zenger. All rights reserved.</string>
2325
</dict>
2426
</plist>

Tests/NumberKitTests/NumberUtilTests.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// NumberKit
44
//
55
// Created by Matthias Zenger on 12/08/2015.
6-
// Copyright © 2015-2019 Matthias Zenger. All rights reserved.
6+
// Copyright © 2015-2020 Matthias Zenger. All rights reserved.
77
//
88
// Licensed under the Apache License, Version 2.0 (the "License");
99
// you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@
2121
import XCTest
2222
@testable import NumberKit
2323

24-
2524
class NumberUtilTests: XCTestCase {
2625

2726
func testPow() {

Tests/NumberKitTests/RationalTests.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// NumberKit
44
//
55
// Created by Matthias Zenger on 16/08/2015.
6-
// Copyright © 2015-2019 Matthias Zenger. All rights reserved.
6+
// Copyright © 2015-2020 Matthias Zenger. All rights reserved.
77
//
88
// Licensed under the Apache License, Version 2.0 (the "License");
99
// you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@
2121
import XCTest
2222
@testable import NumberKit
2323

24-
2524
class RationalTests: XCTestCase {
2625

2726
func testConstructors() {

0 commit comments

Comments
 (0)