Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add compile-time safety for Edges #351

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion Cartography/Edge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,19 @@ import UIKit
import AppKit
#endif

public struct Edge : Property, RelativeEquality, RelativeInequality, Addition, Multiplication {
public struct EdgeXAxis : Property, RelativeEquality, RelativeInequality, Addition, Multiplication {
public let attribute: LayoutAttribute
public let context: Context
public let item: AnyObject

internal init(_ context: Context, _ item: AnyObject, _ attribute: LayoutAttribute) {
self.attribute = attribute
self.context = context
self.item = item
}
}

public struct EdgeYAxis : Property, RelativeEquality, RelativeInequality, Addition, Multiplication {
public let attribute: LayoutAttribute
public let context: Context
public let item: AnyObject
Expand Down
96 changes: 52 additions & 44 deletions Cartography/LayoutProxy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,124 +25,132 @@ extension LayoutProxy {
return Dimension(context, item, attribute)
}

internal func edge(with attribute: NSLayoutConstraint.Attribute) -> Edge {
return Edge(context, item, attribute)
internal func xEdge(with attribute: NSLayoutConstraint.Attribute) -> EdgeXAxis {
return EdgeXAxis(context, item, attribute)
}

internal func yEdge(with attribute: NSLayoutConstraint.Attribute) -> EdgeYAxis {
return EdgeYAxis(context, item, attribute)
}
#elseif os(OSX)
internal func dimension(with attribute: NSLayoutConstraint.Attribute) -> Dimension {
return Dimension(context, item, attribute)
}

internal func edge(with attribute: NSLayoutConstraint.Attribute) -> Edge {
return Edge(context, item, attribute)
internal func xEdge(with attribute: NSLayoutConstraint.Attribute) -> EdgeXAxis {
return EdgeXAxis(context, item, attribute)
}

internal func yEdge(with attribute: NSLayoutConstraint.Attribute) -> EdgeYAxis {
return EdgeYAxis(context, item, attribute)
}
#endif

internal func point(for attr1: Edge, _ attr2: Edge) -> Point {
internal func point(for attr1: EdgeXAxis, _ attr2: EdgeYAxis) -> Point {
return Point(context, [attr1, attr2])
}

internal func size(for attr1: Dimension, _ attr2: Dimension) -> Size {
return Size(context, [attr1, attr2])
}

internal func edges(for attr1: Edge, _ attr2: Edge, _ attr3: Edge, _ attr4: Edge) -> Edges {
internal func edges(for attr1: EdgeYAxis, _ attr2: EdgeXAxis, _ attr3: EdgeYAxis, _ attr4: EdgeXAxis) -> Edges {
return Edges(context, [attr1, attr2, attr3, attr4])
}
}

public protocol SupportsTopLayoutProxy: LayoutProxy {}
extension SupportsTopLayoutProxy {
/// The top edge of the item.
public var top: Edge {
return edge(with: .top)
public var top: EdgeYAxis {
return yEdge(with: .top)
}

#if os(iOS) || os(tvOS)
/// The top margin of the item. iOS exclusive.
@available(iOS, introduced: 8.0)
public var topMargin: Edge {
return edge(with: .topMargin)
public var topMargin: EdgeYAxis {
return yEdge(with: .topMargin)
}
#endif
}

public protocol SupportsBottomLayoutProxy: LayoutProxy {}
extension SupportsBottomLayoutProxy {
/// The bottom edge of the item.
public var bottom: Edge {
return edge(with: .bottom)
public var bottom: EdgeYAxis {
return yEdge(with: .bottom)
}

#if os(iOS) || os(tvOS)
/// The bottom margin of the item. iOS exclusive.
@available(iOS, introduced: 8.0)
public var bottomMargin: Edge {
return edge(with: .bottomMargin)
public var bottomMargin: EdgeYAxis {
return yEdge(with: .bottomMargin)
}
#endif
}

public protocol SupportsRightLayoutProxy: LayoutProxy {}
extension SupportsRightLayoutProxy {
/// The right edge of the item.
public var right: Edge {
return edge(with: .right)
public var right: EdgeXAxis {
return xEdge(with: .right)
}

#if os(iOS) || os(tvOS)
/// The right margin of the item. iOS exclusive.
@available(iOS, introduced: 8.0)
public var rightMargin: Edge {
return edge(with: .rightMargin)
public var rightMargin: EdgeXAxis {
return xEdge(with: .rightMargin)
}
#endif
}

public protocol SupportsLeftLayoutProxy: LayoutProxy {}
extension SupportsLeftLayoutProxy {
/// The left edge of the item.
public var left: Edge {
return edge(with: .left)
public var left: EdgeXAxis {
return xEdge(with: .left)
}

#if os(iOS) || os(tvOS)
/// The left margin of the item. iOS exclusive.
@available(iOS, introduced: 8.0)
public var leftMargin: Edge {
return edge(with: .leftMargin)
public var leftMargin: EdgeXAxis {
return xEdge(with: .leftMargin)
}
#endif
}

public protocol SupportsLeadingLayoutProxy: LayoutProxy {}
extension SupportsLeadingLayoutProxy {
/// The leading edge of the item.
public var leading: Edge {
return edge(with: .leading)
public var leading: EdgeXAxis {
return xEdge(with: .leading)
}

#if os(iOS) || os(tvOS)
/// The leading margin of the item. iOS exclusive.
@available(iOS, introduced: 8.0)
public var leadingMargin: Edge {
return edge(with: .leadingMargin)
public var leadingMargin: EdgeXAxis {
return xEdge(with: .leadingMargin)
}
#endif
}

public protocol SupportsTrailingLayoutProxy: LayoutProxy {}
extension SupportsTrailingLayoutProxy {
/// The trailing edge of the item.
public var trailing: Edge {
return edge(with: .trailing)
public var trailing: EdgeXAxis {
return xEdge(with: .trailing)
}

#if os(iOS) || os(tvOS)
/// The trailing margin of the item. iOS exclusive.
@available(iOS, introduced: 8.0)
public var trailingMargin: Edge {
return edge(with: .trailingMargin)
public var trailingMargin: EdgeXAxis {
return xEdge(with: .trailingMargin)
}
#endif
}
Expand All @@ -169,31 +177,31 @@ extension SupportsEdgesLayoutProxy {
public protocol SupportsCenterXLayoutProxy: LayoutProxy {}
extension SupportsCenterXLayoutProxy {
/// The horizontal center of the item.
public var centerX: Edge {
return edge(with: .centerX)
public var centerX: EdgeXAxis {
return xEdge(with: .centerX)
}

#if os(iOS) || os(tvOS)
/// The horizontal center within the margins of the item. iOS exclusive.
@available(iOS, introduced: 8.0)
public var centerXWithinMargins: Edge {
return edge(with: .centerXWithinMargins)
public var centerXWithinMargins: EdgeXAxis {
return xEdge(with: .centerXWithinMargins)
}
#endif
}

public protocol SupportsCenterYLayoutProxy: LayoutProxy {}
extension SupportsCenterYLayoutProxy {
/// The vertical center of the item.
public var centerY: Edge {
return edge(with: .centerY)
public var centerY: EdgeYAxis {
return yEdge(with: .centerY)
}

#if os(iOS) || os(tvOS)
/// The vertical center within the margins of the item. iOS exclusive.
@available(iOS, introduced: 8.0)
public var centerYWithinMargins: Edge {
return edge(with: .centerYWithinMargins)
public var centerYWithinMargins: EdgeYAxis {
return yEdge(with: .centerYWithinMargins)
}
#endif
}
Expand Down Expand Up @@ -243,20 +251,20 @@ extension SupportsSizeLayoutProxy {
public protocol SupportsBaselineLayoutProxy: LayoutProxy {}
extension SupportsBaselineLayoutProxy {
/// The last baseline of the item.
public var lastBaseline: Edge {
return edge(with: .lastBaseline)
public var lastBaseline: EdgeYAxis {
return yEdge(with: .lastBaseline)
}

/// The baseline of the item.
public var baseline: Edge {
return edge(with: .lastBaseline)
public var baseline: EdgeYAxis {
return yEdge(with: .lastBaseline)
}

/// The first baseline of the item. iOS exclusive.
@available(iOS, introduced: 8.0)
@available(OSX, introduced: 10.11)
public var firstBaseline: Edge {
return edge(with: .firstBaseline)
public var firstBaseline: EdgeYAxis {
return yEdge(with: .firstBaseline)
}
}

Expand Down