Skip to content

Commit 2bdf3a1

Browse files
committed
完成数组的SmartCompact
1 parent 1dcf32d commit 2bdf3a1

3 files changed

Lines changed: 93 additions & 71 deletions

File tree

Example/SmartCodable/TestViewController.swift

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,31 @@ class TestViewController: BaseViewController {
3232

3333
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
3434
let dict: [String: Any] = [
35-
"frinds": ["Tom", 1],
35+
"ages": ["Tom", 1, [:], 2, 3, "4"],
36+
"frinds": [
37+
[], ["name": "Tom"], ["name": "小明"], ["name": "Mccc"],
38+
],
39+
"others": [1, "Tom", ["name": "Tom"]]
3640
]
3741

3842
guard let student = Model.deserialize(from: dict) else { return }
39-
print("⭐️解析结果: my_name = \(student.frinds)")
43+
print("⭐️解析结果: ages = \(student.ages)")
44+
print("⭐️解析结果: frinds = \(student.frinds)")
45+
print("⭐️解析结果: others = \(student.others)")
46+
}
47+
struct Model: SmartCodableX {
48+
@SmartCompact
49+
var ages: [Int] = []
50+
@SmartCompact
51+
var frinds: [Frind] = []
52+
53+
@SmartCompact
54+
var others: [Any] = []
4055
}
4156

42-
43-
struct Model: SmartDecodable {
44-
@SmartLossy
45-
var frinds: [Int] = []
57+
struct Frind: SmartCodableX {
58+
var name: String = ""
4659
}
4760
}
4861

4962

50-
51-
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//
2+
// SmartCompact.swift
3+
// SmartCodable
4+
//
5+
// Created by Mccc on 2026/1/21.
6+
//
7+
8+
@propertyWrapper
9+
public struct SmartCompact<T>: PropertyWrapperable {
10+
11+
public var wrappedValue: [T]
12+
13+
public init(wrappedValue: [T]) {
14+
self.wrappedValue = wrappedValue
15+
}
16+
17+
public func wrappedValueDidFinishMapping() -> SmartCompact? {
18+
guard var temp = wrappedValue as? SmartDecodable else { return nil }
19+
temp.didFinishMapping()
20+
return SmartCompact(wrappedValue: temp as! [T])
21+
}
22+
23+
/// Creates an instance from any value if possible
24+
public static func createInstance(with value: Any) -> SmartCompact? {
25+
guard let value = value as? [T] else { return nil }
26+
return SmartCompact(wrappedValue: value)
27+
}
28+
}
29+
30+
extension SmartCompact: Codable {
31+
public init(from decoder: Decoder) throws {
32+
var container = try decoder.unkeyedContainer()
33+
var result: [T] = []
34+
35+
36+
// 1. 生成 decode 闭包
37+
let decodeValue: () -> Any? = {
38+
if T.self is SmartCodableX.Type,
39+
let type = T.self as? Decodable.Type {
40+
return try? container.decode(type)
41+
} else {
42+
return try? container.decode(SmartAnyImpl.self).peel
43+
}
44+
}
45+
46+
// 2. 统一循环
47+
while !container.isAtEnd {
48+
let startIndex = container.currentIndex
49+
defer {
50+
// 如果 decode 失败,确保 index 被推进
51+
if container.currentIndex == startIndex {
52+
_ = try? container.decode(DummyDecodable.self)
53+
}
54+
}
55+
56+
// decode
57+
if let value = decodeValue(), let v = value as? T {
58+
result.append(v)
59+
}
60+
}
61+
62+
self.wrappedValue = result
63+
}
64+
65+
public func encode(to encoder: Encoder) throws {
66+
var container = encoder.unkeyedContainer()
67+
for value in wrappedValue {
68+
try container.encode(SmartAnyImpl(from: value))
69+
}
70+
}
71+
}
72+
73+
74+
private struct DummyDecodable: Decodable { }

Sources/SmartCodable/Core/PropertyWrapper/SmartLossy.swift

Lines changed: 0 additions & 63 deletions
This file was deleted.

0 commit comments

Comments
 (0)