Skip to content

Commit 2f1b4d0

Browse files
authored
fix: nil as input (#19)
* fix: nil as input * fix: more nil loro value
1 parent 4ca7cba commit 2f1b4d0

File tree

3 files changed

+70
-2
lines changed

3 files changed

+70
-2
lines changed

Sources/Loro/Container.swift

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,6 @@ extension LoroMovableList: ContainerLike{
129129
return typedResult
130130
}
131131
}
132-
extension LoroCounter: ContainerLike{}
133-
extension LoroUnknown: ContainerLike{}
134132

135133

136134
extension LoroList: ContainerLike{
@@ -163,5 +161,50 @@ extension LoroList: ContainerLike{
163161
}
164162
}
165163

164+
extension LoroCounter: ContainerLike{}
165+
extension LoroUnknown: ContainerLike{}
166+
167+
// Extension for handling nil input
168+
// Although we extend Optional, we still need to specify the type explicitly
169+
// e.g. `nil as String?`. This is not convenient in some scenarios.
170+
extension LoroList{
171+
public func insert(pos: UInt32, v: LoroValueLike?) throws {
172+
try self.insert(pos: pos, v: v?.asLoroValue() ?? .null)
173+
}
174+
175+
public func push(v: LoroValueLike?) throws {
176+
try self.push(v: v?.asLoroValue() ?? .null)
177+
}
178+
}
166179

180+
extension LoroMap{
181+
public func insert(key: String, v: LoroValueLike?) throws {
182+
try self.insert(key: key, v: v?.asLoroValue() ?? .null)
183+
}
184+
}
167185

186+
extension LoroMovableList{
187+
public func insert(pos: UInt32, v: LoroValueLike?) throws {
188+
try self.insert(pos: pos, v: v?.asLoroValue() ?? .null)
189+
}
190+
191+
public func push(v: LoroValueLike?) throws {
192+
try self.push(v: v?.asLoroValue() ?? .null)
193+
}
194+
195+
public func set(pos: UInt32, v: LoroValueLike?) throws {
196+
try self.set(pos: pos, value: v?.asLoroValue() ?? .null)
197+
}
198+
}
199+
200+
extension LoroText{
201+
public func mark(from: UInt32, to: UInt32, key: String, value: LoroValueLike?) throws {
202+
try self.mark(from: from, to: to, key: key, value: value?.asLoroValue() ?? .null)
203+
}
204+
}
205+
206+
extension Awareness{
207+
public func setLocalState(value: LoroValueLike?){
208+
self.setLocalState(value: value?.asLoroValue() ?? .null)
209+
}
210+
}

Sources/Loro/Value.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@ extension LoroValue: LoroValueLike {
1212
}
1313
}
1414

15+
extension Optional: LoroValueLike where Wrapped: LoroValueLike {
16+
public func asLoroValue() -> LoroValue {
17+
if let value = self {
18+
return value.asLoroValue()
19+
} else {
20+
return .null
21+
}
22+
}
23+
}
24+
1525
extension Bool: LoroValueLike{
1626
public func asLoroValue() -> LoroValue {
1727
return LoroValue.bool(value: self)

Tests/LoroTests/LoroTests.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,21 @@ final class LoroTests: XCTestCase {
1414
sub.detach()
1515
XCTAssertEqual(num, 1)
1616
}
17+
18+
func testOptional(){
19+
let doc = LoroDoc()
20+
let list = doc.getList(id: "list")
21+
try! list.insert(pos: 0, v: nil)
22+
let map = doc.getMap(id: "map")
23+
try! map.insert(key: "key", v: nil)
24+
let movableList = doc.getMovableList(id: "movableList")
25+
try! movableList.insert(pos: 0, v: nil)
26+
try! movableList.set(pos: 0, v: nil)
27+
doc.commit()
28+
XCTAssertEqual(list.get(index: 0)!.asValue()!, LoroValue.null)
29+
XCTAssertEqual(map.get(key: "key")!.asValue()!, LoroValue.null)
30+
XCTAssertEqual(movableList.get(index: 0)!.asValue()!, LoroValue.null)
31+
}
1732

1833
func testText(){
1934
let doc = LoroDoc()

0 commit comments

Comments
 (0)