Last active
June 5, 2024 08:27
-
-
Save sidepelican/130fd3c61080a071aa176a12083a3e80 to your computer and use it in GitHub Desktop.
resultBuilderと雪だるまジェネリクスで型の組み立て
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
import Foundation | |
@dynamicMemberLookup | |
struct Concat<L: Decodable, R: Decodable>: Decodable { | |
init(left: L, right: R) { | |
self.left = left | |
self.right = right | |
} | |
private var left: L | |
private var right: R | |
subscript<T>(dynamicMember keyPath: KeyPath<L, T>) -> T { | |
left[keyPath: keyPath] | |
} | |
subscript<T>(dynamicMember keyPath: KeyPath<R, T>) -> T { | |
right[keyPath: keyPath] | |
} | |
init(from decoder: any Decoder) throws { | |
var container = try decoder.singleValueContainer() | |
self.left = try container.decode(L.self) | |
self.right = try container.decode(R.self) | |
} | |
} | |
struct p_id: Decodable { | |
var id: Int | |
} | |
struct p_name: Decodable { | |
var name: String | |
} | |
struct p_createdAt: Decodable { | |
var createdAt: Int | |
} | |
@resultBuilder | |
struct RowBuilder { | |
static func buildBlock<T>(_ component: T) -> T { | |
component | |
} | |
static func buildPartialBlock<T: Decodable>(first: T) -> T { | |
first | |
} | |
static func buildPartialBlock<Accumulated, Next>( | |
accumulated: Accumulated, | |
next: Next | |
) -> Concat<Accumulated, Next> | |
{ | |
Concat(left: accumulated, right: next) | |
} | |
} | |
func buildRow<Row>(@RowBuilder _ builder: () -> Row) -> Row { | |
builder() | |
} | |
let row = buildRow { | |
p_id(id: 1) | |
p_name(name: "Taro") | |
p_createdAt(createdAt: 123) | |
} | |
print(row.id) | |
print(row.name) | |
print(row.createdAt) | |
let json = """ | |
{ | |
"id": 2, | |
"name": "Hanako", | |
"createdAt": 456 | |
} | |
""".data(using: .utf8)! | |
func jsonDecode<T: Decodable>(typeOf _: T, from data: Data) throws -> T { | |
return try JSONDecoder().decode(T.self, from: data) | |
} | |
let row2 = try jsonDecode(typeOf: row, from: json) | |
print(row2.id) | |
print(row2.name) | |
print(row2.createdAt) |
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
1 | |
Taro | |
123 | |
2 | |
Hanako | |
456 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment