-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from g-Off/custom-encoder
switching the encoding to being object version aware
- Loading branch information
Showing
46 changed files
with
1,114 additions
and
1,262 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,4 @@ | ||
language: swift | ||
osx_image: xcode10.2 | ||
xcode_project: XcodeProject.xcodeproj | ||
xcode_scheme: XcodeProject | ||
script: | ||
- xcodebuild test -scheme XcodeProject | tee xcodebuild.log | xcpretty && exit ${PIPESTATUS[0]} | ||
- swift test | tee xcodebuild.log | xcpretty && exit ${PIPESTATUS[0]} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// | ||
// AnyCodingKey.swift | ||
// XcodeProject | ||
// | ||
// Created by Geoffrey Foster on 2019-06-19. | ||
// | ||
|
||
import Foundation | ||
|
||
struct AnyCodingKey: CodingKey, Equatable, Hashable { | ||
var stringValue: String | ||
var intValue: Int? | ||
|
||
init?(stringValue: String) { | ||
self.stringValue = stringValue | ||
self.intValue = nil | ||
} | ||
|
||
init?(intValue: Int) { | ||
self.stringValue = "\(intValue)" | ||
self.intValue = intValue | ||
} | ||
|
||
init<Key>(_ base: Key) where Key: CodingKey { | ||
if let intValue = base.intValue { | ||
self.init(intValue: intValue)! | ||
} else { | ||
self.init(stringValue: base.stringValue)! | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// | ||
// PBXEncoder.swift | ||
// XcodeProject | ||
// | ||
// Created by Geoffrey Foster on 2019-06-18. | ||
// | ||
|
||
import Foundation | ||
|
||
class PBXObjectEncoder { | ||
static let objectVersionKey = CodingUserInfoKey(rawValue: "objectVersion")! | ||
var objectVersion: ObjectVersion = .xcode93 | ||
|
||
func encode(_ object: PBXObject) throws -> [String: AnyObject] { | ||
let encoder = _PBXObjectEncoder() | ||
encoder.userInfo = [PBXObjectEncoder.objectVersionKey: objectVersion] | ||
try object.encode(to: encoder) | ||
return encoder.storage.popContainer() as? [String: AnyObject] ?? [:] | ||
} | ||
} | ||
|
||
extension Encoder { | ||
var objectVersion: ObjectVersion { | ||
return userInfo[PBXObjectEncoder.objectVersionKey] as? ObjectVersion ?? ObjectVersion.allCases.last! | ||
} | ||
|
||
// TODO: better name, but this will allow for encode(to:) function to be able to "smartly" decide to encode id's or objects | ||
var supportsCyclic: Bool { | ||
return self is _PBXObjectEncoder | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
Sources/XcodeProject/Archiving/Encoder/_PBXObjectEncoder+KeyedContainer.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// | ||
// _PBXObjectEncoder+KeyedContainer.swift | ||
// XcodeProject | ||
// | ||
// Created by Geoffrey Foster on 2019-06-19. | ||
// | ||
|
||
import Foundation | ||
|
||
extension _PBXObjectEncoder { | ||
final class KeyedContainer<Key> where Key: CodingKey { | ||
private let encoder: _PBXObjectEncoder | ||
var codingPath: [CodingKey] | ||
|
||
private var container: NSMutableDictionary | ||
|
||
init(referencing encoder: _PBXObjectEncoder, codingPath: [CodingKey], wrapping container: NSMutableDictionary) { | ||
self.encoder = encoder | ||
self.codingPath = codingPath | ||
self.container = container | ||
} | ||
} | ||
} | ||
|
||
extension _PBXObjectEncoder.KeyedContainer: KeyedEncodingContainerProtocol { | ||
private func nestedCodingPath(forKey key: CodingKey) -> [CodingKey] { | ||
return self.codingPath + [key] | ||
} | ||
|
||
func encodeNil(forKey key: Key) throws { | ||
container[key.stringValue] = NSNull() | ||
} | ||
|
||
func encode(_ value: String, forKey key: Key) throws { | ||
container[key.stringValue] = NSString(string: value.quotedString) | ||
} | ||
|
||
func encode<T>(_ value: T, forKey key: Key) throws where T: Encodable { | ||
encoder.codingPath.append(key) | ||
defer { encoder.codingPath.removeLast() } | ||
container[key.stringValue] = try encoder.box(value) | ||
} | ||
|
||
func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type, forKey key: Key) -> KeyedEncodingContainer<NestedKey> where NestedKey: CodingKey { | ||
fatalError() | ||
} | ||
|
||
func nestedUnkeyedContainer(forKey key: Key) -> UnkeyedEncodingContainer { | ||
fatalError() | ||
} | ||
|
||
func superEncoder() -> Encoder { | ||
fatalError() | ||
} | ||
|
||
func superEncoder(forKey key: Key) -> Encoder { | ||
fatalError() | ||
} | ||
} |
103 changes: 103 additions & 0 deletions
103
Sources/XcodeProject/Archiving/Encoder/_PBXObjectEncoder+SingleValueContainer.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// | ||
// _PBXObjectEncoder+SingleValueContainer.swift | ||
// XcodeProject | ||
// | ||
// Created by Geoffrey Foster on 2019-06-19. | ||
// | ||
|
||
import Foundation | ||
|
||
extension _PBXObjectEncoder { | ||
final class SingleValueContainer { | ||
private let encoder: _PBXObjectEncoder | ||
var codingPath: [CodingKey] | ||
|
||
init(referencing encoder: _PBXObjectEncoder, codingPath: [CodingKey]) { | ||
self.encoder = encoder | ||
self.codingPath = codingPath | ||
} | ||
} | ||
} | ||
|
||
extension _PBXObjectEncoder.SingleValueContainer: SingleValueEncodingContainer { | ||
private func assertCanEncodeNewValue() { | ||
precondition(encoder.canEncodeNewValue, "Attempt to encode value through single value container when previously value already encoded.") | ||
} | ||
|
||
func encodeNil() throws { | ||
encoder.storage.pushValue(NSNull()) | ||
} | ||
|
||
func encode(_ value: Bool) throws { | ||
assertCanEncodeNewValue() | ||
encoder.storage.pushValue(NSNumber(value: value)) | ||
} | ||
|
||
func encode(_ value: String) throws { | ||
assertCanEncodeNewValue() | ||
encoder.storage.pushValue(NSString(string: value.quotedString)) | ||
} | ||
|
||
func encode(_ value: Double) throws { | ||
throw EncodingError.invalidValue(value, EncodingError.Context(codingPath: codingPath, debugDescription: "Unsupported type: \(type(of: value))")) | ||
} | ||
|
||
func encode(_ value: Float) throws { | ||
throw EncodingError.invalidValue(value, EncodingError.Context(codingPath: codingPath, debugDescription: "Unsupported type: \(type(of: value))")) | ||
} | ||
|
||
func encode(_ value: Int) throws { | ||
assertCanEncodeNewValue() | ||
encoder.storage.pushValue(NSNumber(value: value)) | ||
} | ||
|
||
func encode(_ value: Int8) throws { | ||
assertCanEncodeNewValue() | ||
encoder.storage.pushValue(NSNumber(value: value)) | ||
} | ||
|
||
func encode(_ value: Int16) throws { | ||
assertCanEncodeNewValue() | ||
encoder.storage.pushValue(NSNumber(value: value)) | ||
} | ||
|
||
func encode(_ value: Int32) throws { | ||
assertCanEncodeNewValue() | ||
encoder.storage.pushValue(NSNumber(value: value)) | ||
} | ||
|
||
func encode(_ value: Int64) throws { | ||
assertCanEncodeNewValue() | ||
encoder.storage.pushValue(NSNumber(value: value)) | ||
} | ||
|
||
func encode(_ value: UInt) throws { | ||
assertCanEncodeNewValue() | ||
encoder.storage.pushValue(NSNumber(value: value)) | ||
} | ||
|
||
func encode(_ value: UInt8) throws { | ||
assertCanEncodeNewValue() | ||
encoder.storage.pushValue(NSNumber(value: value)) | ||
} | ||
|
||
func encode(_ value: UInt16) throws { | ||
assertCanEncodeNewValue() | ||
encoder.storage.pushValue(NSNumber(value: value)) | ||
} | ||
|
||
func encode(_ value: UInt32) throws { | ||
assertCanEncodeNewValue() | ||
encoder.storage.pushValue(NSNumber(value: value)) | ||
} | ||
|
||
func encode(_ value: UInt64) throws { | ||
assertCanEncodeNewValue() | ||
encoder.storage.pushValue(NSNumber(value: value)) | ||
} | ||
|
||
func encode<T>(_ value: T) throws where T: Encodable { | ||
assertCanEncodeNewValue() | ||
encoder.storage.pushValue(try encoder.box(value)) | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
Sources/XcodeProject/Archiving/Encoder/_PBXObjectEncoder+UnkeyedContainer.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// | ||
// _PBXObjectEncoder+UnkeyedContainer.swift | ||
// XcodeProject | ||
// | ||
// Created by Geoffrey Foster on 2019-06-19. | ||
// | ||
|
||
import Foundation | ||
|
||
extension _PBXObjectEncoder { | ||
final class UnkeyedContainer { | ||
private let encoder: _PBXObjectEncoder | ||
var codingPath: [CodingKey] | ||
|
||
private var container: NSMutableArray | ||
|
||
init(referencing encoder: _PBXObjectEncoder, codingPath: [CodingKey], wrapping container: NSMutableArray) { | ||
self.encoder = encoder | ||
self.codingPath = codingPath | ||
self.container = container | ||
} | ||
} | ||
} | ||
|
||
extension _PBXObjectEncoder.UnkeyedContainer: UnkeyedEncodingContainer { | ||
private var nestedCodingPath: [CodingKey] { | ||
return codingPath + [AnyCodingKey(intValue: count)!] | ||
} | ||
|
||
var count: Int { | ||
return container.count | ||
} | ||
|
||
func encodeNil() throws { | ||
container.add(NSNull()) | ||
} | ||
|
||
func encode(_ value: String) throws { | ||
container.add(NSString(string: value.quotedString)) | ||
} | ||
|
||
func encode<T>(_ value: T) throws where T: Encodable { | ||
encoder.codingPath.append(AnyCodingKey(intValue: count)!) | ||
defer { encoder.codingPath.removeLast() } | ||
container.add(try encoder.box(value)) | ||
} | ||
|
||
func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer<NestedKey> where NestedKey: CodingKey { | ||
fatalError() | ||
} | ||
|
||
func nestedUnkeyedContainer() -> UnkeyedEncodingContainer { | ||
fatalError() | ||
} | ||
|
||
func superEncoder() -> Encoder { | ||
fatalError() | ||
} | ||
} |
Oops, something went wrong.