-
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
Showing
9 changed files
with
495 additions
and
6 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,102 @@ | ||
|
||
// MARK: Horizontal | ||
|
||
/// A measurement of the horizontal dimension. | ||
public struct Horizontal: Equatable, Hashable { | ||
fileprivate let value: Int | ||
} | ||
|
||
extension Horizontal: AdditiveArithmetic { | ||
public static func + (lhs: Horizontal, rhs: Horizontal) -> Horizontal { | ||
Horizontal(value: lhs.value + rhs.value) | ||
} | ||
|
||
public static func - (lhs: Horizontal, rhs: Horizontal) -> Horizontal { | ||
Horizontal(value: lhs.value - rhs.value) | ||
} | ||
} | ||
|
||
extension Horizontal: Comparable { | ||
public static func < (lhs: Horizontal, rhs: Horizontal) -> Bool { | ||
lhs.value < rhs.value | ||
} | ||
} | ||
|
||
extension Horizontal: CustomStringConvertible { | ||
public var description: String { | ||
value.description | ||
} | ||
} | ||
|
||
extension Horizontal: ExpressibleByIntegerLiteral { | ||
public init(integerLiteral value: Int) { | ||
self.init(value: value) | ||
} | ||
} | ||
|
||
extension Horizontal: Strideable { | ||
public func advanced(by n: Int) -> Horizontal { | ||
Horizontal(value: value + n) | ||
} | ||
|
||
public func distance(to other: Horizontal) -> Int { | ||
value - other.value | ||
} | ||
} | ||
|
||
extension Horizontal { | ||
package init(_ value: some BinaryInteger) { | ||
self.init(value: Int(value)) | ||
} | ||
} | ||
|
||
// MARK: - Vertical | ||
|
||
/// A measurement of the vertical dimension. | ||
public struct Vertical: Equatable, Hashable { | ||
fileprivate let value: Int | ||
} | ||
|
||
extension Vertical: AdditiveArithmetic { | ||
public static func + (lhs: Vertical, rhs: Vertical) -> Vertical { | ||
Vertical(value: lhs.value + rhs.value) | ||
} | ||
|
||
public static func - (lhs: Vertical, rhs: Vertical) -> Vertical { | ||
Vertical(value: lhs.value - rhs.value) | ||
} | ||
} | ||
|
||
extension Vertical: Comparable { | ||
public static func < (lhs: Vertical, rhs: Vertical) -> Bool { | ||
lhs.value < rhs.value | ||
} | ||
} | ||
|
||
extension Vertical: CustomStringConvertible { | ||
public var description: String { | ||
value.description | ||
} | ||
} | ||
|
||
extension Vertical: ExpressibleByIntegerLiteral { | ||
public init(integerLiteral value: Int) { | ||
self.init(value: value) | ||
} | ||
} | ||
|
||
extension Vertical: Strideable { | ||
public func advanced(by n: Int) -> Vertical { | ||
Vertical(value: value + n) | ||
} | ||
|
||
public func distance(to other: Vertical) -> Int { | ||
value - other.value | ||
} | ||
} | ||
|
||
extension Vertical { | ||
package init(_ value: some BinaryInteger) { | ||
self.init(value: Int(value)) | ||
} | ||
} |
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 @@ | ||
|
||
public enum Edge {} | ||
|
||
extension Edge { | ||
public struct Set<Value> { | ||
fileprivate let _insets: (Value) -> EdgeInsets | ||
} | ||
} | ||
|
||
extension Edge.Set { | ||
func insets(_ value: Value) -> EdgeInsets { | ||
_insets(value) | ||
} | ||
} | ||
|
||
extension Edge.Set<Int> { | ||
|
||
public static var all: Self { | ||
Self { value in | ||
let vertical = Vertical(value) | ||
let horizontal = Horizontal(value) | ||
return EdgeInsets( | ||
top: vertical, | ||
leading: horizontal, | ||
bottom: vertical, | ||
trailing: horizontal) | ||
} | ||
} | ||
} | ||
|
||
extension Edge.Set<Vertical> { | ||
|
||
public static var top: Self { | ||
Self { EdgeInsets(top: $0, leading: 0, bottom: 0, trailing: 0) } | ||
} | ||
|
||
public static var bottom: Self { | ||
Self { EdgeInsets(top: 0, leading: 0, bottom: $0, trailing: 0) } | ||
} | ||
|
||
public static var vertical: Self { | ||
Self { EdgeInsets(top: $0, leading: 0, bottom: $0, trailing: 0) } | ||
} | ||
} | ||
|
||
extension Edge.Set<Horizontal> { | ||
|
||
public static var leading: Self { | ||
Self { EdgeInsets(top: 0, leading: $0, bottom: 0, trailing: 0) } | ||
} | ||
|
||
public static var trailing: Self { | ||
Self { EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: $0) } | ||
} | ||
|
||
public static var horizontal: Self { | ||
Self { EdgeInsets(top: 0, leading: $0, bottom: 0, trailing: $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,19 @@ | ||
|
||
public struct EdgeInsets { | ||
let top: Vertical | ||
let leading: Horizontal | ||
let bottom: Vertical | ||
let trailing: Horizontal | ||
|
||
public init( | ||
top: Vertical, | ||
leading: Horizontal, | ||
bottom: Vertical, | ||
trailing: Horizontal | ||
) { | ||
self.top = top | ||
self.leading = leading | ||
self.bottom = bottom | ||
self.trailing = trailing | ||
} | ||
} |
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,15 +1,15 @@ | ||
import Foundation | ||
|
||
struct Size { | ||
let width: Int | ||
let height: Int | ||
let width: Horizontal | ||
let height: Vertical | ||
} | ||
|
||
extension Size { | ||
|
||
static var window: Size { | ||
var size = winsize() | ||
_ = ioctl(STDOUT_FILENO, UInt(TIOCGWINSZ), &size) | ||
return Size(width: Int(size.ws_col), height: Int(size.ws_row)) | ||
return Size(width: Horizontal(size.ws_col), height: Vertical(size.ws_row)) | ||
} | ||
} |
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,66 @@ | ||
|
||
extension View { | ||
|
||
public func padding(_ insets: EdgeInsets) -> some View { | ||
Padding(content: self, insets: insets) | ||
} | ||
|
||
public func padding<Value>( | ||
_ set: Edge.Set<Value>, | ||
_ value: Value | ||
) -> some View { | ||
padding(set.insets(value)) | ||
} | ||
|
||
public func padding(_ length: Int) -> some View { | ||
padding(.all, length) | ||
} | ||
} | ||
|
||
private struct Padding<Content: View>: Builtin, View { | ||
|
||
let content: Content | ||
let insets: EdgeInsets | ||
|
||
func render( | ||
in canvas: any Canvas, | ||
size: Size, | ||
environment: EnvironmentValues | ||
) { | ||
content._render( | ||
in: canvas.inset(insets), | ||
size: size.inset(insets), | ||
environment: environment | ||
) | ||
} | ||
} | ||
|
||
extension Canvas { | ||
fileprivate func inset(_ insets: EdgeInsets) -> Canvas { | ||
InsetCanvas(base: self, insets: insets) | ||
} | ||
} | ||
|
||
private struct InsetCanvas<Base: Canvas>: Canvas { | ||
let base: Base | ||
let insets: EdgeInsets | ||
|
||
func draw(_ pixel: Pixel, at position: Position) { | ||
base.draw(pixel, at: position.offset(by: insets)) | ||
} | ||
} | ||
|
||
extension Position { | ||
fileprivate func offset(by insets: EdgeInsets) -> Position { | ||
Position(x: x + insets.leading, y: y + insets.top) | ||
} | ||
} | ||
|
||
extension Size { | ||
fileprivate func inset(_ insets: EdgeInsets) -> Size { | ||
Size( | ||
width: width - insets.leading - insets.trailing, | ||
height: height - insets.top - insets.bottom | ||
) | ||
} | ||
} |
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 |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import TerminalUI | ||
import TerminalUITesting | ||
import Testing | ||
|
||
@Suite("Dimensions") struct DimensionTests { | ||
|
||
@Suite("Horizontal") struct HorizontalTests { | ||
|
||
@Test("ExpressibleByIntegerLiteral") | ||
func expressibleByIntegerLiteral() { | ||
let horizontal: Horizontal = 3 | ||
#expect(horizontal.description == "3") | ||
} | ||
|
||
@Test("AdditiveArithmetic") | ||
func additiveArithmetic() { | ||
#expect(Horizontal(4) + Horizontal(2) == Horizontal(6)) | ||
#expect(Horizontal(4) - Horizontal(2) == Horizontal(2)) | ||
} | ||
|
||
@Test("Comparable") | ||
func comparable() { | ||
#expect(Horizontal(1) < Horizontal(2)) | ||
#expect(Horizontal(2) > Horizontal(1)) | ||
#expect(Horizontal(1) <= Horizontal(1)) | ||
#expect(Horizontal(1) >= Horizontal(1)) | ||
} | ||
|
||
@Test("Equatable") | ||
func equatable() { | ||
#expect(Horizontal(1) == Horizontal(1)) | ||
#expect(Horizontal(2) != Horizontal(1)) | ||
} | ||
|
||
@Test("Strideable") | ||
func strideable() { | ||
var horizontals = (Horizontal(1)...Horizontal(3)).makeIterator() | ||
#expect(horizontals.next() == 1) | ||
#expect(horizontals.next() == 2) | ||
#expect(horizontals.next() == 3) | ||
#expect(horizontals.next() == nil) | ||
} | ||
|
||
@Test("init(some BinaryInteger)") | ||
func initBinaryInteger() { | ||
let value = Int.random(in: 0..<1_000_000) | ||
#expect(Horizontal(value).description == value.description) | ||
} | ||
} | ||
|
||
@Suite("Vertical") struct VerticalTests { | ||
|
||
@Test("AdditiveArithmetic") | ||
func additiveArithmetic() { | ||
#expect(Vertical(4) + Vertical(2) == Vertical(6)) | ||
#expect(Vertical(4) - Vertical(2) == Vertical(2)) | ||
} | ||
|
||
@Test("Comparable") | ||
func comparable() { | ||
#expect(Vertical(1) < Vertical(2)) | ||
#expect(Vertical(2) > Vertical(1)) | ||
#expect(Vertical(1) <= Vertical(1)) | ||
#expect(Vertical(1) >= Vertical(1)) | ||
} | ||
|
||
@Test("Equatable") | ||
func equatable() { | ||
#expect(Vertical(1) == Vertical(1)) | ||
#expect(Vertical(2) != Vertical(1)) | ||
} | ||
|
||
@Test("ExpressibleByIntegerLiteral") | ||
func expressibleByIntegerLiteral() { | ||
let vertical: Vertical = 3 | ||
#expect(vertical.description == "3") | ||
} | ||
|
||
@Test("Strideable") | ||
func strideable() { | ||
var verticals = (Vertical(1)...Vertical(3)).makeIterator() | ||
#expect(verticals.next() == 1) | ||
#expect(verticals.next() == 2) | ||
#expect(verticals.next() == 3) | ||
#expect(verticals.next() == nil) | ||
} | ||
|
||
@Test("init(some BinaryInteger)") | ||
func initBinaryInteger() { | ||
let value: Int = Int.random(in: 0..<1_000_000) | ||
#expect(Vertical(value).description == value.description) | ||
} | ||
} | ||
} |
Oops, something went wrong.