feat: Working on node builder

This commit is contained in:
2024-12-01 11:45:05 -05:00
parent 55d8888961
commit ff49b12198
20 changed files with 495 additions and 227 deletions

View File

@@ -28,4 +28,75 @@ public enum NodeBuilder {
.second(component)
}
public static func buildBlock<N: NodeRepresentable>(_ components: N...) -> _ManyNode {
.init(components)
}
// This breaks things ??
// public static func buildExpression<N: NodeRepresentable>(_ expression: N) -> AnyNode {
// expression.eraseToAnyNode()
// }
public static func buildOptional<N: NodeRepresentable>(_ component: N?) -> AnyNode {
component?.eraseToAnyNode() ?? AnyNode { Text.empty() }
}
public static func buildFinalResult<N: NodeRepresentable>(_ component: N) -> N {
component
}
public static func buildLimitedAvailability<N: NodeRepresentable>(_ component: N) -> N {
component
}
}
// These are nodes that are only used by the `NodeBuilder` / internally.
// swiftlint:disable type_name
public enum _ConditionalNode<
TrueNode: NodeRepresentable,
FalseNode: NodeRepresentable
>: NodeRepresentable {
case first(TrueNode)
case second(FalseNode)
public func render() -> String {
switch self {
case let .first(node): return node.render()
case let .second(node): return node.render()
}
}
}
public struct _ManyNode: NodeRepresentable {
@usableFromInline
let nodes: [any NodeRepresentable]
@usableFromInline
let separator: any NodeRepresentable
@usableFromInline
init(
_ nodes: [any NodeRepresentable],
separator: AnyNode = Text.empty().eraseToAnyNode()
) {
self.nodes = nodes
self.separator = separator
}
@inlinable
public init(_ nodes: [any NodeRepresentable], separator: any NodeRepresentable) {
self.nodes = nodes
self.separator = separator
}
@inlinable
public func render() -> String {
nodes.map { $0.render() }
.joined(separator: separator.render())
}
}
// swiftlint:enable type_name