From d2bc328ad281343018ea125c543d4d5923f7fd11 Mon Sep 17 00:00:00 2001 From: Jayson Rhynas Date: Thu, 27 Apr 2023 15:00:54 -0400 Subject: [PATCH] Split Edge type into EdgeXAxis and EdgeYAxis types Provides compile-time safety to ensure that invalid constraints are not created between edges on different axes --- Cartography/Edge.swift | 14 ++++- Cartography/LayoutProxy.swift | 96 +++++++++++++++++++---------------- 2 files changed, 65 insertions(+), 45 deletions(-) diff --git a/Cartography/Edge.swift b/Cartography/Edge.swift index 439b8db0..2b7ad9ce 100644 --- a/Cartography/Edge.swift +++ b/Cartography/Edge.swift @@ -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 diff --git a/Cartography/LayoutProxy.swift b/Cartography/LayoutProxy.swift index d342db77..4ec9e262 100644 --- a/Cartography/LayoutProxy.swift +++ b/Cartography/LayoutProxy.swift @@ -25,20 +25,28 @@ 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]) } @@ -46,7 +54,7 @@ extension LayoutProxy { 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]) } } @@ -54,15 +62,15 @@ extension LayoutProxy { 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 } @@ -70,15 +78,15 @@ extension SupportsTopLayoutProxy { 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 } @@ -86,15 +94,15 @@ extension SupportsBottomLayoutProxy { 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 } @@ -102,15 +110,15 @@ extension SupportsRightLayoutProxy { 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 } @@ -118,15 +126,15 @@ extension SupportsLeftLayoutProxy { 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 } @@ -134,15 +142,15 @@ extension SupportsLeadingLayoutProxy { 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 } @@ -169,15 +177,15 @@ 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 } @@ -185,15 +193,15 @@ extension SupportsCenterXLayoutProxy { 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 } @@ -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) } }