ぜのぜ

しりとりしようぜのぜのぜのぜ

95日目

日記

餃子作るぞーと材料買ってきたはいいがお菓子を食べちゃったのであんまりお腹がすいてない.

今日書いたコード

https://docs.swift.org/swift-book/LanguageGuide/AdvancedOperators.html

protocol Drawable {
    func draw() -> String
}
struct Line: Drawable {
    var elements: [Drawable]
    func draw() -> String {
        return elements.map { $0.draw() }.joined(separator: "")
    }
}
struct Text: Drawable {
    var content: String
    init(_ content: String) { self.content = content }
    func draw() -> String { return content }
}
struct Space: Drawable {
    func draw() -> String { return " " }
}
struct Stars: Drawable {
    var length: Int
    func draw() -> String { return String(repeating: "*", count: length) }
}
struct AllCaps: Drawable {
    var content: Drawable
    func draw() -> String { return content.draw().uppercased() }
}
struct Empty: Drawable {
    func draw() -> String {
        ""
    }
}

@resultBuilder
struct DrawingBuilder {
    static func buildBlock(_ components: Drawable...) -> Drawable {
        print("\(#function)", components)
        return Line(elements: components)
    }
    static func buildEither(first: Drawable) -> Drawable {
        print("\(#function)", first)
        return first
    }
    static func buildEither(second: Drawable) -> Drawable {
        print("\(#function)", second)
        return second
    }
}

func draw(@DrawingBuilder content: () -> Drawable) -> Drawable {
    return content()
}
func caps(@DrawingBuilder content: () -> Drawable) -> Drawable {
    return AllCaps(content: content())
}

func makeGreeting(for name: String? = nil) -> Drawable {
    let greeting = draw {
        Stars(length: 3)
        Text("Hello")
        Space()
        caps {
            if let name = name {
                Text(name + "!")
            } else {
                Text("World!")
            }
        }
        Stars(length: 2)
    }
    return greeting
}
let genericGreeting = makeGreeting()
print(genericGreeting.draw())

感想

いかにもSwiftUIのために作りましたという感じが出ている.ちょうど金曜日にViewBuilder気持ち悪いなーと思っていたので種が分かってすっきりした.