Skip to content

Commit

Permalink
Sendable fix (#41)
Browse files Browse the repository at this point in the history
* fix: resolves Sendable warning (swift concurrency) for Prop
* chore: Swiftformat updates for existing Marks code
  • Loading branch information
heckj committed Jul 3, 2023
1 parent a40e37d commit ad50545
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 18 deletions.
20 changes: 17 additions & 3 deletions Sources/Automerge/Document.swift
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ public class Document: @unchecked Sendable {
}

/// Add or remove a mark to a given range of text
///
///
/// - Parameters:
/// - obj: The text object to which to add the mark.
/// - start: The index position, in UTF-8 code points, where the function starts the mark.
Expand All @@ -375,10 +375,24 @@ public class Document: @unchecked Sendable {
///
/// To remove an existing mark between two index positions, set the name to the same value
/// as the existing mark and set the value to the scalar value ``ScalarValue/Null``.
public func mark(obj: ObjId, start: UInt64, end: UInt64, expand: ExpandMark, name: String, value: ScalarValue) throws {
public func mark(
obj: ObjId,
start: UInt64,
end: UInt64,
expand: ExpandMark,
name: String,
value: ScalarValue
) throws {
try queue.sync {
try self.doc.wrapErrors {
try $0.mark(obj: obj.bytes, start: start, end: end, expand: expand.toFfi(), name: name, value: value.toFfi())
try $0.mark(
obj: obj.bytes,
start: start,
end: end,
expand: expand.toFfi(),
name: name,
value: value.toFfi()
)
}
}
}
Expand Down
7 changes: 3 additions & 4 deletions Sources/Automerge/Marks.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import struct AutomergeUniffi.Mark
import enum AutomergeUniffi.ExpandMark
import struct AutomergeUniffi.Mark

typealias FfiMark = AutomergeUniffi.Mark
typealias FfiExpandMark = AutomergeUniffi.ExpandMark


/// A type that represents a marked range of text.
///
/// Marks are annotations to text, which can be used to identify additional formatting, or other indicators relevant to the text at a specific location.
/// Marks are annotations to text, which can be used to identify additional formatting, or other indicators relevant to
/// the text at a specific location.
/// The are identified by a string `name` and have an associated ``ScalarValue``.
public struct Mark: Equatable, Hashable, Sendable {
/// The utf-8 codepoint index of the start of the mark
Expand All @@ -29,7 +29,6 @@ public struct Mark: Equatable, Hashable, Sendable {
static func fromFfi(_ ffiMark: FfiMark) -> Self {
Self(start: ffiMark.start, end: ffiMark.end, name: ffiMark.name, value: Value.fromFfi(value: ffiMark.value))
}

}

/// A type that indicates how a mark should expand when adding characters at the ends of the mark.
Expand Down
2 changes: 1 addition & 1 deletion Sources/Automerge/Patch.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public enum PatchAction: Equatable {
case let .insert(obj, index, values, marks):
return .Insert(
obj: ObjId(bytes: obj),
index: index,
index: index,
values: values.map { Value.fromFfi(value: $0) },
marks: marks.mapValues(Value.fromFfi)
)
Expand Down
2 changes: 1 addition & 1 deletion Sources/Automerge/PathElement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public struct PathElement: Equatable {
///
/// The property is either a ``Prop/Key(_:)``, in the from of a `String` to a map,
/// or a ``Prop/Index(_:)`` with the index position represented as a 64-bit unsigned integer.
public enum Prop: Equatable {
public enum Prop: Equatable, Sendable {
/// A property in a map.
case Key(String)
/// An index into a sequence.
Expand Down
32 changes: 23 additions & 9 deletions Tests/AutomergeTests/TestMarks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,17 @@ class MarksTestCase: XCTestCase {
let doc = Document()
let text = try! doc.putObject(obj: ObjId.ROOT, key: "text", ty: ObjType.Text)
try! doc.spliceText(obj: text, start: 0, delete: 0, value: "Hello marks")
try! doc.mark(obj: text, start: 0, end: 5, expand: ExpandMark.none, name: "bold", value: ScalarValue.Boolean(true))
let marks = try! doc.marks(obj:text)
try! doc.mark(
obj: text,
start: 0,
end: 5,
expand: ExpandMark.none,
name: "bold",
value: ScalarValue.Boolean(true)
)
let marks = try! doc.marks(obj: text)
let expectedMarks = [
Mark(start: 0, end: 5, name: "bold", value: Value.Scalar(ScalarValue.Boolean(true)))
Mark(start: 0, end: 5, name: "bold", value: Value.Scalar(ScalarValue.Boolean(true))),
]
XCTAssertEqual(marks, expectedMarks)

Expand All @@ -18,11 +25,11 @@ class MarksTestCase: XCTestCase {

// Now remove the mark
try! doc.mark(obj: text, start: 0, end: 5, expand: ExpandMark.none, name: "bold", value: ScalarValue.Null)
let marksAfterDelete = try! doc.marks(obj:text)
let marksAfterDelete = try! doc.marks(obj: text)
XCTAssertEqual(marksAfterDelete.count, 0)

// Now check that marksAt still returns the marks
let marksAt = try! doc.marksAt(obj:text, heads: heads)
let marksAt = try! doc.marksAt(obj: text, heads: heads)
XCTAssertEqual(marksAt, expectedMarks)
}

Expand All @@ -33,22 +40,29 @@ class MarksTestCase: XCTestCase {

// Make the marks on a fork so we can see the marks in patches when we merge
let fork = doc.fork()
try! fork.mark(obj: text, start: 0, end: 5, expand: ExpandMark.none, name: "bold", value: ScalarValue.Boolean(true))
try! fork.mark(
obj: text,
start: 0,
end: 5,
expand: ExpandMark.none,
name: "bold",
value: ScalarValue.Boolean(true)
)
let patches = try! doc.mergeWithPatches(other: fork)
let expectedMarks = [
Mark(start: 0, end: 5, name: "bold", value: Value.Scalar(ScalarValue.Boolean(true)))
Mark(start: 0, end: 5, name: "bold", value: Value.Scalar(ScalarValue.Boolean(true))),
]
XCTAssertEqual(patches, [Patch(
action: .Marks(text, expectedMarks),
path: [PathElement(obj: ObjId.ROOT,prop:.Key("text")) ]
path: [PathElement(obj: ObjId.ROOT, prop: .Key("text"))]
)])

// Now splice some text in the fork and make sure the splice patch contains the marks
try! fork.spliceText(obj: text, start: 4, delete: 0, value: "oo")
let patchesAfterSplice = try! doc.mergeWithPatches(other: fork)
XCTAssertEqual(patchesAfterSplice, [Patch(
action: .SpliceText(obj: text, index: 4, value: "oo", marks: ["bold": .Scalar(.Boolean(true))]),
path: [PathElement(obj: ObjId.ROOT,prop:.Key("text")) ]
path: [PathElement(obj: ObjId.ROOT, prop: .Key("text"))]
)])
}
}

0 comments on commit ad50545

Please sign in to comment.