1
1
mirror of https://github.com/github/semantic.git synced 2024-12-22 14:21:31 +03:00
semantic/prototype/Doubt/Patch.swift

91 lines
1.8 KiB
Swift
Raw Normal View History

2015-10-02 23:36:05 +03:00
/// A patch to some part of a `Syntax` tree.
2015-10-06 23:45:36 +03:00
public enum Patch<A>: CustomDebugStringConvertible {
case Replace(Fix<A>, Fix<A>)
case Insert(Fix<A>)
case Delete(Fix<A>)
2015-10-02 23:38:21 +03:00
public var state: (before: Fix<A>?, after: Fix<A>?) {
2015-10-02 23:38:02 +03:00
switch self {
case let .Replace(a, b):
return (a, b)
case let .Insert(b):
return (nil, b)
case let .Delete(a):
return (a, nil)
2015-10-02 23:38:02 +03:00
}
}
2015-10-06 23:45:36 +03:00
/// The cost of a patch to the diff.
public var cost: Int {
switch self {
case .Replace:
return 2
default:
return 1
}
}
2015-10-07 15:41:54 +03:00
public var inverse: Patch {
switch self {
case let .Replace(a, b):
return .Replace(b, a)
case let .Insert(b):
return .Delete(b)
case let .Delete(a):
return .Insert(a)
}
}
2015-10-06 23:45:36 +03:00
// MARK: CustomDebugStringConvertible
public var debugDescription: String {
switch self {
case let .Replace(a, b):
return ".Replace(\(String(reflecting: a)), \(String(reflecting: b)))"
case let .Insert(b):
return ".Insert(\(String(reflecting: b)))"
case let .Delete(a):
return ".Delete(\(String(reflecting: a)))"
}
}
2015-10-02 23:34:00 +03:00
}
2015-10-02 23:49:04 +03:00
// MARK: - Equality
extension Patch {
public static func equals(param: (A, A) -> Bool)(_ left: Patch, _ right: Patch) -> Bool {
return Optional.equals(Fix.equals(param))(left.state.before, right.state.before)
&& Optional.equals(Fix.equals(param))(left.state.after, right.state.after)
}
}
2015-10-02 23:50:59 +03:00
// MARK: - Hashing
extension Patch {
public func hash(param: A -> Hash) -> Hash {
return Hash.Ordered([
state.before.map { $0.hash(param) } ?? Hash.Empty,
state.after.map { $0.hash(param) } ?? Hash.Empty
])
}
}
2015-10-07 04:25:21 +03:00
/// A hack to enable constrained extensions on `Free<A, Patch<A>>`.
public protocol PatchConvertible {
typealias Info
init(patch: Patch<Info>)
var patch: Patch<Info> { get }
}
2015-10-07 04:24:43 +03:00
extension Patch: PatchConvertible {
public init(patch: Patch) { self = patch }
public var patch: Patch { return self }
}