Files
swift-cli-doc/Sources/CliDocCore/Nodes/Separator.swift
Michael Housh c6a269f062
All checks were successful
CI / Run tests. (push) Successful in 52s
feat: Adds stack separators, removes some unused nodes from cli-doc module
2024-12-08 10:58:03 -05:00

117 lines
3.4 KiB
Swift

/// A namespace for separator types that are used in text nodes.
///
/// These are generally used in the ``HStack``'s and ``VStack``'s to
/// specifiy how the nodes they contain are separated.
///
///
/// **Note:**
///
/// > By default nodes do not contain any separators, unless they are written inline.
/// > However, both ``HStack`` and ``VStack`` allow you to specify the separator to use
/// > to control how the individual nodes they contain are separated.
///
public enum Separator {
/// Represents a horizontal separator that can be used between text nodes, typically inside
/// an ``HStack``
///
/// **Note:**
/// > By default nodes do not contain any separators, unless they are written inline.
///
public enum Horizontal: TextNode {
/// Separate nodes by spaces of the given count.
case space(count: Int = 1)
/// Separate nodes by tabs of the given count.
case tab(count: Int = 1)
/// Separate nodes by the provided string of the given count.
///
/// **Note:**
///
/// > This can allow for non-sensical separators, so should only be used
/// > if the provided horizontal separators do not work for you.
///
case custom(String, count: Int = 1)
@TextBuilder
@inlinable
public var body: some TextNode {
switch self {
case let .tab(count: count):
makeSeperator("\t", count: count)
case let .space(count: count):
makeSeperator(" ", count: count)
case let .custom(string, count: count):
makeSeperator(string, count: count)
}
}
}
/// Represents a vertical separator that can be used between text nodes, typically inside
/// a ``VStack``
///
/// **Note:**
/// > By default nodes do not contain any separators, so if you would
/// > like a blank line separating nodes, then a count of `2` is required.
/// > A count of `1` will place nodes on the next line.
///
public enum Vertical: TextNode {
/// Separate nodes by new line characters of the given count.
///
/// **Note:**
/// > By default nodes do not contain any separtors, so if you would
/// > like a blank line separating nodes, then a count of `2` is required.
/// > A count of `1` will place nodes on the next line.
///
///
/// - Parameters:
/// - count: The count of the new lines to use.
case newLine(count: Int = 1)
/// Separate nodes by the supplied string with the given count.
///
/// **Note:**
///
/// > This can allow for non-sensical separators, so should only be used
/// > if the provided vertical separators do not work for you.
///
/// - Parameters:
/// - count: The count of the new lines to use.
case custom(String, count: Int = 1)
@TextBuilder
@inlinable
public var body: some TextNode {
switch self {
case let .newLine(count: count):
makeSeperator("\n", count: count)
case let .custom(string, count: count):
makeSeperator(string, count: count)
}
}
}
}
// MARK: - Private Helpers.
@usableFromInline
func ensuredCount(_ count: Int) -> Int {
guard count >= 1 else { return 1 }
return count
}
@usableFromInline
func makeSeperator(_ separator: String, count: Int) -> some TextNode {
let count = ensuredCount(count)
assert(count >= 1, "Invalid count while creating a separator")
var output = ""
for _ in 1 ... count {
output += separator
}
return output
}