Some code,
typealias Brio = (String, String, String)
extension Brio {
static var divider: Brio {
return ("_", "_", "_")
}
static var isDivider: Bool {
return (self.0 == "_")
}
}
Tuple extension must be written as extension of '(repeat each Element)',
Tuple extension must declare conformance to exactly one protocol
Tuple extensions are experimental
I really couldn't figure it out from say this chat,
https://forums.swift.org/t/pitch-user-defined-tuple-conformances/67154
I don't understand the following sort of stuff but if relevant:
fattie@m2max203mbp16 ~ % swift --version
swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
Target: arm64-apple-macosx14.0
fattie@m2max203mbp16 ~ %
Coin use case:
Here's an example of where extending tuples would be sweet
// Setup the screen selector button
screensButton.showsMenuAsPrimaryAction = true
let noms = [
Brio("CA", "Cats", "cat.fill"),
Brio("DO", "Dogs", "fido.circle"),
Brio("DO", "Horsies", "equine.circle"),
.divider,
Brio("DEV", "Dev reload", "link"),
Brio("DX", "Dev, clear", "circle"),
.divider,
Brio("XX", "Example", "circle.dotted"),
Brio("XX", "Example", "link"),
]
var elements = noms.chompchomp(){ k in self.screensButtonProcess(k) }
screensButton.menu = UIMenu(children: elements)
Having to use a class is annoying. It would be more purer with tuples, eg,
let noms = [
("CA", "Cats", "cat.fill"),
("DO", "Dogs", "fido.circle"),
("DO", "Horsies", "equine.circle"),
.divider,
("DEV", "Dev reload", "link"),
Footnote, here's the kodes for chompchomp, done with tears as a class Brio rather than tuples:
///A "BUTTON TRIO". Internal code, title, system image.
///
///Use `[Brio]` to make menus. Just put `.divider` where you want dividers.
///
///OR just use `buildBrios { }` if using the matching @resultBuilder
struct Brio {
let c: String
let t: String
let i: String
var isDivider: Bool = false
}
extension Brio {
init(_ x: String, _ y: String, _ z: String) {
self.init(c: x, t: y, i: z)
}
///When you type-out a `Brio` array just put `.divider` where you want dividers.
static var divider: Brio {
return Brio(c: "_", t: "_", i: "_", isDivider: true)
}
}
extension [Brio] {
///Chew on an array of `Brio` and spit out the UIMenuElement array. Recall that to create dividers in UIKit menus, basically each run (other than the first) is marked as inline.
func chompchomp(with: @escaping (_ tapped: String)-> ()) -> [UIMenuElement] {
var brios = self
var result = brios.chomp().elements{ b in with(b) }
var run = brios.chomp().elements(with: { b in with(b) })
while !run.isEmpty {
result.append(UIMenu(options: .displayInline, children: run))
run = brios.chomp().elements(with: { b in with(b) })
}
return result
}
///Simply give the next run of menu items removing that run.
mutating func chomp() -> [Brio] {
let spl = self.split(maxSplits: 1, whereSeparator: { $0.isDivider })
self = (spl.count < 2) ? [] : Array(spl[1])
return (spl.count < 1) ? [] : Array(spl[0])
}
///Alchemize one run of Brio into an array of UIMenuElement.
func elements(with: @escaping (_ tapped: String)-> ()) -> [UIMenuElement] {
return self.map({ brio in
return UIAction(title: brio.t, image: UIImage(systemName: brio.i)) { _ in
with(brio.c)
}
})
}
}
* it's hilarious that cat.fill actually exists!


Extensions on tuples must conform tuples of any number of elements to a protocol. Your use case only makes sense to use 3-tuples, so a tuple extension isn't very suitable.
You should keep your
Briostruct, and create a result builder forBrios,Then you can achieve a usage like this:
You cannot use the
.dividersyntax in a result builder (See here). You can writeBrio.divider, or use a separate struct (I have borrowed theDividerfrom SwiftUI here).You can extend this further by implementing
buildArray,buildIf, etc in the result builder. This would allow you to use loops and if statements in the result builder closure. For more information, see the Swift Evolution proposal.