forked from ra1028/DifferenceKit
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit b3bc03b
Showing
27 changed files
with
2,999 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
.DS_Store | ||
*/build/* | ||
*.pbxuser | ||
!default.pbxuser | ||
*.mode1v3 | ||
!default.mode1v3 | ||
*.mode2v3 | ||
!default.mode2v3 | ||
*.perspectivev3 | ||
!default.perspectivev3 | ||
xcuserdata | ||
profile | ||
*.moved-aside | ||
DerivedData | ||
.idea/ | ||
*.hmap | ||
*.xccheckout | ||
*.xcuserstate |
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 @@ | ||
4.1 |
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,15 @@ | ||
env: | ||
global: | ||
- LC_CTYPE=en_US.UTF-8 | ||
matrix: | ||
include: | ||
- os: osx | ||
language: objective-c | ||
osx_image: xcode9.4 | ||
script: | ||
- set -o pipefail | ||
- xcodebuild build-for-testing test-without-building -scheme DifferenceKit -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 8' ENABLE_TESTABILITY=YES | xcpretty - c | ||
- xcodebuild build-for-testing test-without-building -scheme DifferenceKit -configuration Release -sdk appletvsimulator -destination 'platform=tvOS Simulator,name=Apple TV' ENABLE_TESTABILITY=YES | xcpretty -c | ||
|
||
notifications: | ||
email: false |
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,21 @@ | ||
SWIFT_VERSION = 4.1 | ||
|
||
IPHONEOS_DEPLOYMENT_TARGET = 9.0 | ||
TVOS_DEPLOYMENT_TARGET = 9.0 | ||
|
||
SDKROOT = | ||
SUPPORTED_PLATFORMS = iphoneos iphonesimulator appletvos appletvsimulator | ||
TARGETED_DEVICE_FAMILY = 1,2,3 | ||
VALID_ARCHS[sdk=iphoneos*] = arm64 armv7 armv7s | ||
VALID_ARCHS[sdk=iphonesimulator*] = i386 x86_64 | ||
VALID_ARCHS[sdk=appletv*] = arm64 | ||
VALID_ARCHS[sdk=appletvsimulator*] = x86_64 | ||
|
||
CODE_SIGN_IDENTITY = | ||
CODE_SIGN_STYLE = Manual | ||
INSTALL_PATH = $(LOCAL_LIBRARY_DIR)/Frameworks | ||
SKIP_INSTALL = YES | ||
DYLIB_COMPATIBILITY_VERSION = 1 | ||
DYLIB_CURRENT_VERSION = 1 | ||
DYLIB_INSTALL_NAME_BASE = @rpath | ||
LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks @loader_path/Frameworks @loader_path/../Frameworks |
Large diffs are not rendered by default.
Oops, something went wrong.
7 changes: 7 additions & 0 deletions
7
DifferenceKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
8 changes: 8 additions & 0 deletions
8
DifferenceKit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
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,8 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http:https://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>IDEDidComputeMac32BitWarning</key> | ||
<true/> | ||
</dict> | ||
</plist> |
99 changes: 99 additions & 0 deletions
99
DifferenceKit.xcodeproj/xcshareddata/xcschemes/DifferenceKit.xcscheme
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,99 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<Scheme | ||
LastUpgradeVersion = "0930" | ||
version = "1.3"> | ||
<BuildAction | ||
parallelizeBuildables = "YES" | ||
buildImplicitDependencies = "YES"> | ||
<BuildActionEntries> | ||
<BuildActionEntry | ||
buildForTesting = "YES" | ||
buildForRunning = "YES" | ||
buildForProfiling = "YES" | ||
buildForArchiving = "YES" | ||
buildForAnalyzing = "YES"> | ||
<BuildableReference | ||
BuildableIdentifier = "primary" | ||
BlueprintIdentifier = "6B2DF86D210E2C12004D2D40" | ||
BuildableName = "DifferenceKit.framework" | ||
BlueprintName = "DifferenceKit" | ||
ReferencedContainer = "container:DifferenceKit.xcodeproj"> | ||
</BuildableReference> | ||
</BuildActionEntry> | ||
</BuildActionEntries> | ||
</BuildAction> | ||
<TestAction | ||
buildConfiguration = "Release" | ||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
shouldUseLaunchSchemeArgsEnv = "YES"> | ||
<Testables> | ||
<TestableReference | ||
skipped = "NO"> | ||
<BuildableReference | ||
BuildableIdentifier = "primary" | ||
BlueprintIdentifier = "6B2DF876210E2C12004D2D40" | ||
BuildableName = "DifferenceKitTests.xctest" | ||
BlueprintName = "DifferenceKitTests" | ||
ReferencedContainer = "container:DifferenceKit.xcodeproj"> | ||
</BuildableReference> | ||
</TestableReference> | ||
</Testables> | ||
<MacroExpansion> | ||
<BuildableReference | ||
BuildableIdentifier = "primary" | ||
BlueprintIdentifier = "6B2DF86D210E2C12004D2D40" | ||
BuildableName = "DifferenceKit.framework" | ||
BlueprintName = "DifferenceKit" | ||
ReferencedContainer = "container:DifferenceKit.xcodeproj"> | ||
</BuildableReference> | ||
</MacroExpansion> | ||
<AdditionalOptions> | ||
</AdditionalOptions> | ||
</TestAction> | ||
<LaunchAction | ||
buildConfiguration = "Debug" | ||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
launchStyle = "0" | ||
useCustomWorkingDirectory = "NO" | ||
ignoresPersistentStateOnLaunch = "NO" | ||
debugDocumentVersioning = "YES" | ||
debugServiceExtension = "internal" | ||
allowLocationSimulation = "YES"> | ||
<MacroExpansion> | ||
<BuildableReference | ||
BuildableIdentifier = "primary" | ||
BlueprintIdentifier = "6B2DF86D210E2C12004D2D40" | ||
BuildableName = "DifferenceKit.framework" | ||
BlueprintName = "DifferenceKit" | ||
ReferencedContainer = "container:DifferenceKit.xcodeproj"> | ||
</BuildableReference> | ||
</MacroExpansion> | ||
<AdditionalOptions> | ||
</AdditionalOptions> | ||
</LaunchAction> | ||
<ProfileAction | ||
buildConfiguration = "Release" | ||
shouldUseLaunchSchemeArgsEnv = "YES" | ||
savedToolIdentifier = "" | ||
useCustomWorkingDirectory = "NO" | ||
debugDocumentVersioning = "YES"> | ||
<MacroExpansion> | ||
<BuildableReference | ||
BuildableIdentifier = "primary" | ||
BlueprintIdentifier = "6B2DF86D210E2C12004D2D40" | ||
BuildableName = "DifferenceKit.framework" | ||
BlueprintName = "DifferenceKit" | ||
ReferencedContainer = "container:DifferenceKit.xcodeproj"> | ||
</BuildableReference> | ||
</MacroExpansion> | ||
</ProfileAction> | ||
<AnalyzeAction | ||
buildConfiguration = "Debug"> | ||
</AnalyzeAction> | ||
<ArchiveAction | ||
buildConfiguration = "Release" | ||
revealArchiveInOrganizer = "YES"> | ||
</ArchiveAction> | ||
</Scheme> |
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,62 @@ | ||
/// A type-erased differentiable value. | ||
/// | ||
/// The `AnyDifferentiable` type hides the specific underlying types. | ||
/// `DifferenceIdentifier` type is erased by `AnyHashable`. | ||
/// The comparisons of whether has updated is forwards to an underlying differentiable value. | ||
/// | ||
/// You can store mixed-type elements in collection that require `Differentiable` conformance by | ||
/// wrapping mixed-type elements in `AnyDifferentiable`: | ||
/// | ||
/// extension String: Differentiable {} | ||
/// extension Int: Differentiable {} | ||
/// | ||
/// let source: [AnyDifferentiable] = [ | ||
/// AnyDifferentiable("ABC"), | ||
/// AnyDifferentiable(100) | ||
/// ] | ||
/// let target: [AnyDifferentiable] = [ | ||
/// AnyDifferentiable("ABC"), | ||
/// AnyDifferentiable(100), | ||
/// AnyDifferentiable(200) | ||
/// ] | ||
/// | ||
/// let changeset = StagedChangeset(source: source, target: target) | ||
/// print(changeset.isEmpty) // prints "false" | ||
public struct AnyDifferentiable: Differentiable { | ||
/// The value wrapped by this instance. | ||
public let base: Any | ||
/// A type-erased identifier value for differentiation. | ||
public let differenceIdentifier: AnyHashable | ||
|
||
private let isUpdatedFrom: (AnyDifferentiable) -> Bool | ||
|
||
/// Creates a type-erased differentiable value that wraps the given instance. | ||
/// | ||
/// - Parameters: | ||
/// - base: A differentiable value to wrap. | ||
public init<D: Differentiable>(_ base: D) { | ||
self.base = base | ||
self.differenceIdentifier = AnyHashable(base.differenceIdentifier) | ||
|
||
self.isUpdatedFrom = { source in | ||
guard let sourceBase = source.base as? D else { return false } | ||
return base.isUpdated(from: sourceBase) | ||
} | ||
} | ||
|
||
/// Indicate whether `base` has updated from given source value. | ||
/// | ||
/// - Parameters: | ||
/// - source: A source value to be compared. | ||
/// | ||
/// - Returns: A Boolean value indicating whether `base` has updated from given source value. | ||
public func isUpdated(from source: AnyDifferentiable) -> Bool { | ||
return isUpdatedFrom(source) | ||
} | ||
} | ||
|
||
extension AnyDifferentiable: CustomDebugStringConvertible { | ||
public var debugDescription: String { | ||
return "AnyDifferentiable(\(String(reflecting: base))" | ||
} | ||
} |
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,129 @@ | ||
/// A set of changes in the sectioned collection. | ||
/// | ||
/// Changes to the section of the linear collection should be empty. | ||
/// | ||
/// Notice that the value of the changes represents offsets of collection not index. | ||
/// Since offsets are unordered, order is ignored when comparing two `Changeset`s. | ||
public struct Changeset<Collection: Swift.Collection> { | ||
/// The collection after changed. | ||
public var data: Collection | ||
|
||
/// The offsets of deleted sections. | ||
public var sectionDeleted: [Int] | ||
/// The offsets of inserted sections. | ||
public var sectionInserted: [Int] | ||
/// The offsets of updated sections. | ||
public var sectionUpdated: [Int] | ||
/// The pairs of source and target offset of moved sections. | ||
public var sectionMoved: [(source: Int, target: Int)] | ||
|
||
/// The paths of deleted elements. | ||
public var elementDeleted: [ElementPath] | ||
/// The paths of inserted elements. | ||
public var elementInserted: [ElementPath] | ||
/// The paths of updated elements. | ||
public var elementUpdated: [ElementPath] | ||
/// The pairs of source and target path of moved elements. | ||
public var elementMoved: [(source: ElementPath, target: ElementPath)] | ||
|
||
/// The number of all changes. | ||
public var changesCount: Int { | ||
return sectionDeleted.count | ||
+ sectionInserted.count | ||
+ sectionUpdated.count | ||
+ sectionMoved.count | ||
+ elementDeleted.count | ||
+ elementInserted.count | ||
+ elementUpdated.count | ||
+ elementMoved.count | ||
} | ||
|
||
/// A Boolean value indicating whether has changes. | ||
public var hasChanges: Bool { | ||
return changesCount > 0 | ||
} | ||
|
||
/// Creates a new `Changeset`. | ||
/// | ||
/// - Parameters: | ||
/// - data: The collection after changed. | ||
/// - sectionDeleted: The offsets of deleted sections. | ||
/// - sectionInserted: The offsets of inserted sections. | ||
/// - sectionUpdated: The offsets of updated sections. | ||
/// - sectionMoved: The pairs of source and target offset of moved sections. | ||
/// - elementDeleted: The paths of deleted elements. | ||
/// - elementInserted: The paths of inserted elements. | ||
/// - elementUpdated: The paths of updated elements. | ||
/// - elementMoved: The pairs of source and target path of moved elements. | ||
public init( | ||
data: Collection, | ||
sectionDeleted: [Int] = [], | ||
sectionInserted: [Int] = [], | ||
sectionUpdated: [Int] = [], | ||
sectionMoved: [(source: Int, target: Int)] = [], | ||
elementDeleted: [ElementPath] = [], | ||
elementInserted: [ElementPath] = [], | ||
elementUpdated: [ElementPath] = [], | ||
elementMoved: [(source: ElementPath, target: ElementPath)] = [] | ||
) { | ||
self.data = data | ||
self.sectionDeleted = sectionDeleted | ||
self.sectionInserted = sectionInserted | ||
self.sectionUpdated = sectionUpdated | ||
self.sectionMoved = sectionMoved | ||
self.elementDeleted = elementDeleted | ||
self.elementInserted = elementInserted | ||
self.elementUpdated = elementUpdated | ||
self.elementMoved = elementMoved | ||
} | ||
} | ||
|
||
extension Changeset: Equatable where Collection: Equatable { | ||
public static func == (lhs: Changeset, rhs: Changeset) -> Bool { | ||
return lhs.data == rhs.data | ||
&& Set(lhs.sectionDeleted) == Set(rhs.sectionDeleted) | ||
&& Set(lhs.sectionInserted) == Set(rhs.sectionInserted) | ||
&& Set(lhs.sectionUpdated) == Set(rhs.sectionUpdated) | ||
&& Set(lhs.sectionMoved.map(HashablePair.init)) == Set(rhs.sectionMoved.map(HashablePair.init)) | ||
&& Set(lhs.elementDeleted) == Set(rhs.elementDeleted) | ||
&& Set(lhs.elementInserted) == Set(rhs.elementInserted) | ||
&& Set(lhs.elementUpdated) == Set(rhs.elementUpdated) | ||
&& Set(lhs.elementMoved.map(HashablePair.init)) == Set(rhs.elementMoved.map(HashablePair.init)) | ||
} | ||
} | ||
|
||
extension Changeset: CustomDebugStringConvertible { | ||
public var debugDescription: String { | ||
guard !data.isEmpty || hasChanges else { | ||
return "Changeset(data: [])" | ||
} | ||
|
||
var description = """ | ||
Changeset( | ||
data: \(data.isEmpty ? "[]" : "[\n \(data.map { "\($0)" }.joined(separator: ",\n").split(separator: "\n").joined(separator: "\n "))\n ]") | ||
""" | ||
|
||
func appendDescription<T>(name: String, elements: [T]) { | ||
guard !elements.isEmpty else { return } | ||
|
||
description += ",\n \(name): [\n \(elements.map { "\($0)" }.joined(separator: ",\n").split(separator: "\n").joined(separator: "\n "))\n ]" | ||
} | ||
|
||
appendDescription(name: "sectionDeleted", elements: sectionDeleted) | ||
appendDescription(name: "sectionInserted", elements: sectionInserted) | ||
appendDescription(name: "sectionUpdated", elements: sectionUpdated) | ||
appendDescription(name: "sectionMoved", elements: sectionMoved) | ||
appendDescription(name: "elementDeleted", elements: elementDeleted) | ||
appendDescription(name: "elementInserted", elements: elementInserted) | ||
appendDescription(name: "elementUpdated", elements: elementUpdated) | ||
appendDescription(name: "elementMoved", elements: elementMoved) | ||
|
||
description += "\n)" | ||
return description | ||
} | ||
} | ||
|
||
private struct HashablePair<H: Hashable>: Hashable { | ||
let first: H | ||
let second: H | ||
} |
Oops, something went wrong.