Skip to content

Commit d12280d

Browse files
authored
updating mark API to align with core library, exposing split_block and join_block through to Swift (#171)
* switches mark to take ScalarValue explicitly, not Value * split_block and join_block, using u32 to approx usize in API * shift the Swift marks over to using ScalarValue to match the Rust core API change
1 parent 26ccaf9 commit d12280d

File tree

7 files changed

+317
-15
lines changed

7 files changed

+317
-15
lines changed

AutomergeUniffi/automerge.swift

+262-4
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,19 @@ private struct FfiConverterUInt8: FfiConverterPrimitive {
393393
}
394394
}
395395

396+
private struct FfiConverterUInt32: FfiConverterPrimitive {
397+
typealias FfiType = UInt32
398+
typealias SwiftType = UInt32
399+
400+
public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> UInt32 {
401+
try lift(readInt(&buf))
402+
}
403+
404+
public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
405+
writeInt(&buf, lower(value))
406+
}
407+
}
408+
396409
private struct FfiConverterUInt64: FfiConverterPrimitive {
397410
typealias FfiType = UInt64
398411
typealias SwiftType = UInt64
@@ -554,6 +567,8 @@ public protocol DocProtocol: AnyObject {
554567

555568
func insertObjectInList(obj: ObjId, index: UInt64, objType: ObjType) throws -> ObjId
556569

570+
func joinBlock(obj: ObjId, index: UInt32) throws
571+
557572
func length(obj: ObjId) -> UInt64
558573

559574
func lengthAt(obj: ObjId, heads: [ChangeHash]) -> UInt64
@@ -600,6 +615,8 @@ public protocol DocProtocol: AnyObject {
600615

601616
func spliceText(obj: ObjId, start: UInt64, delete: Int64, chars: String) throws
602617

618+
func splitBlock(obj: ObjId, index: UInt32) throws -> ObjId
619+
603620
func text(obj: ObjId) throws -> String
604621

605622
func textAt(obj: ObjId, heads: [ChangeHash]) throws -> String
@@ -1008,6 +1025,16 @@ open class Doc:
10081025
})
10091026
}
10101027

1028+
open func joinBlock(obj: ObjId, index: UInt32) throws { try rustCallWithError(FfiConverterTypeDocError.lift) {
1029+
uniffi_uniffi_automerge_fn_method_doc_join_block(
1030+
self.uniffiClonePointer(),
1031+
FfiConverterTypeObjId.lower(obj),
1032+
FfiConverterUInt32.lower(index),
1033+
$0
1034+
)
1035+
}
1036+
}
1037+
10111038
open func length(obj: ObjId) -> UInt64 {
10121039
try! FfiConverterUInt64.lift(try! rustCall {
10131040
uniffi_uniffi_automerge_fn_method_doc_length(
@@ -1267,6 +1294,17 @@ open class Doc:
12671294
}
12681295
}
12691296

1297+
open func splitBlock(obj: ObjId, index: UInt32) throws -> ObjId {
1298+
try FfiConverterTypeObjId.lift(rustCallWithError(FfiConverterTypeDocError.lift) {
1299+
uniffi_uniffi_automerge_fn_method_doc_split_block(
1300+
self.uniffiClonePointer(),
1301+
FfiConverterTypeObjId.lower(obj),
1302+
FfiConverterUInt32.lower(index),
1303+
$0
1304+
)
1305+
})
1306+
}
1307+
12701308
open func text(obj: ObjId) throws -> String {
12711309
try FfiConverterString.lift(rustCallWithError(FfiConverterTypeDocError.lift) {
12721310
uniffi_uniffi_automerge_fn_method_doc_text(
@@ -1630,15 +1668,58 @@ public func FfiConverterTypeKeyValue_lower(_ value: KeyValue) -> RustBuffer {
16301668
FfiConverterTypeKeyValue.lower(value)
16311669
}
16321670

1671+
public struct MapValue {
1672+
public var value: [String: AmValue]
1673+
1674+
// Default memberwise initializers are never public by default, so we
1675+
// declare one manually.
1676+
public init(value: [String: AmValue]) {
1677+
self.value = value
1678+
}
1679+
}
1680+
1681+
extension MapValue: Equatable, Hashable {
1682+
public static func == (lhs: MapValue, rhs: MapValue) -> Bool {
1683+
if lhs.value != rhs.value {
1684+
return false
1685+
}
1686+
return true
1687+
}
1688+
1689+
public func hash(into hasher: inout Hasher) {
1690+
hasher.combine(value)
1691+
}
1692+
}
1693+
1694+
public struct FfiConverterTypeMapValue: FfiConverterRustBuffer {
1695+
public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> MapValue {
1696+
try MapValue(
1697+
value: FfiConverterDictionaryStringTypeAMValue.read(from: &buf)
1698+
)
1699+
}
1700+
1701+
public static func write(_ value: MapValue, into buf: inout [UInt8]) {
1702+
FfiConverterDictionaryStringTypeAMValue.write(value.value, into: &buf)
1703+
}
1704+
}
1705+
1706+
public func FfiConverterTypeMapValue_lift(_ buf: RustBuffer) throws -> MapValue {
1707+
try FfiConverterTypeMapValue.lift(buf)
1708+
}
1709+
1710+
public func FfiConverterTypeMapValue_lower(_ value: MapValue) -> RustBuffer {
1711+
FfiConverterTypeMapValue.lower(value)
1712+
}
1713+
16331714
public struct Mark {
16341715
public var start: UInt64
16351716
public var end: UInt64
16361717
public var name: String
1637-
public var value: Value
1718+
public var value: ScalarValue
16381719

16391720
// Default memberwise initializers are never public by default, so we
16401721
// declare one manually.
1641-
public init(start: UInt64, end: UInt64, name: String, value: Value) {
1722+
public init(start: UInt64, end: UInt64, name: String, value: ScalarValue) {
16421723
self.start = start
16431724
self.end = end
16441725
self.name = name
@@ -1677,15 +1758,15 @@ public struct FfiConverterTypeMark: FfiConverterRustBuffer {
16771758
start: FfiConverterUInt64.read(from: &buf),
16781759
end: FfiConverterUInt64.read(from: &buf),
16791760
name: FfiConverterString.read(from: &buf),
1680-
value: FfiConverterTypeValue.read(from: &buf)
1761+
value: FfiConverterTypeScalarValue.read(from: &buf)
16811762
)
16821763
}
16831764

16841765
public static func write(_ value: Mark, into buf: inout [UInt8]) {
16851766
FfiConverterUInt64.write(value.start, into: &buf)
16861767
FfiConverterUInt64.write(value.end, into: &buf)
16871768
FfiConverterString.write(value.name, into: &buf)
1688-
FfiConverterTypeValue.write(value.value, into: &buf)
1769+
FfiConverterTypeScalarValue.write(value.value, into: &buf)
16891770
}
16901771
}
16911772

@@ -1799,6 +1880,132 @@ public func FfiConverterTypePathElement_lower(_ value: PathElement) -> RustBuffe
17991880
FfiConverterTypePathElement.lower(value)
18001881
}
18011882

1883+
public struct TextValue {
1884+
public var value: String
1885+
public var marks: [Mark]
1886+
1887+
// Default memberwise initializers are never public by default, so we
1888+
// declare one manually.
1889+
public init(value: String, marks: [Mark]) {
1890+
self.value = value
1891+
self.marks = marks
1892+
}
1893+
}
1894+
1895+
extension TextValue: Equatable, Hashable {
1896+
public static func == (lhs: TextValue, rhs: TextValue) -> Bool {
1897+
if lhs.value != rhs.value {
1898+
return false
1899+
}
1900+
if lhs.marks != rhs.marks {
1901+
return false
1902+
}
1903+
return true
1904+
}
1905+
1906+
public func hash(into hasher: inout Hasher) {
1907+
hasher.combine(value)
1908+
hasher.combine(marks)
1909+
}
1910+
}
1911+
1912+
public struct FfiConverterTypeTextValue: FfiConverterRustBuffer {
1913+
public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TextValue {
1914+
try TextValue(
1915+
value: FfiConverterString.read(from: &buf),
1916+
marks: FfiConverterSequenceTypeMark.read(from: &buf)
1917+
)
1918+
}
1919+
1920+
public static func write(_ value: TextValue, into buf: inout [UInt8]) {
1921+
FfiConverterString.write(value.value, into: &buf)
1922+
FfiConverterSequenceTypeMark.write(value.marks, into: &buf)
1923+
}
1924+
}
1925+
1926+
public func FfiConverterTypeTextValue_lift(_ buf: RustBuffer) throws -> TextValue {
1927+
try FfiConverterTypeTextValue.lift(buf)
1928+
}
1929+
1930+
public func FfiConverterTypeTextValue_lower(_ value: TextValue) -> RustBuffer {
1931+
FfiConverterTypeTextValue.lower(value)
1932+
}
1933+
1934+
// Note that we don't yet support `indirect` for enums.
1935+
// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion.
1936+
1937+
public enum AmValue {
1938+
case scalar(
1939+
value: ScalarValue
1940+
)
1941+
case list(
1942+
value: [AmValue]
1943+
)
1944+
case map(
1945+
value: MapValue
1946+
)
1947+
case text(
1948+
value: TextValue
1949+
)
1950+
}
1951+
1952+
public struct FfiConverterTypeAMValue: FfiConverterRustBuffer {
1953+
typealias SwiftType = AmValue
1954+
1955+
public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> AmValue {
1956+
let variant: Int32 = try readInt(&buf)
1957+
switch variant {
1958+
case 1: return try .scalar(
1959+
value: FfiConverterTypeScalarValue.read(from: &buf)
1960+
)
1961+
1962+
case 2: return try .list(
1963+
value: FfiConverterSequenceTypeAMValue.read(from: &buf)
1964+
)
1965+
1966+
case 3: return try .map(
1967+
value: FfiConverterTypeMapValue.read(from: &buf)
1968+
)
1969+
1970+
case 4: return try .text(
1971+
value: FfiConverterTypeTextValue.read(from: &buf)
1972+
)
1973+
1974+
default: throw UniffiInternalError.unexpectedEnumCase
1975+
}
1976+
}
1977+
1978+
public static func write(_ value: AmValue, into buf: inout [UInt8]) {
1979+
switch value {
1980+
case let .scalar(value):
1981+
writeInt(&buf, Int32(1))
1982+
FfiConverterTypeScalarValue.write(value, into: &buf)
1983+
1984+
case let .list(value):
1985+
writeInt(&buf, Int32(2))
1986+
FfiConverterSequenceTypeAMValue.write(value, into: &buf)
1987+
1988+
case let .map(value):
1989+
writeInt(&buf, Int32(3))
1990+
FfiConverterTypeMapValue.write(value, into: &buf)
1991+
1992+
case let .text(value):
1993+
writeInt(&buf, Int32(4))
1994+
FfiConverterTypeTextValue.write(value, into: &buf)
1995+
}
1996+
}
1997+
}
1998+
1999+
public func FfiConverterTypeAMValue_lift(_ buf: RustBuffer) throws -> AmValue {
2000+
try FfiConverterTypeAMValue.lift(buf)
2001+
}
2002+
2003+
public func FfiConverterTypeAMValue_lower(_ value: AmValue) -> RustBuffer {
2004+
FfiConverterTypeAMValue.lower(value)
2005+
}
2006+
2007+
extension AmValue: Equatable, Hashable {}
2008+
18022009
public enum DecodeSyncStateError {
18032010
case Internal(message: String)
18042011
}
@@ -2685,6 +2892,28 @@ private struct FfiConverterSequenceTypePathElement: FfiConverterRustBuffer {
26852892
}
26862893
}
26872894

2895+
private struct FfiConverterSequenceTypeAMValue: FfiConverterRustBuffer {
2896+
typealias SwiftType = [AmValue]
2897+
2898+
public static func write(_ value: [AmValue], into buf: inout [UInt8]) {
2899+
let len = Int32(value.count)
2900+
writeInt(&buf, len)
2901+
for item in value {
2902+
FfiConverterTypeAMValue.write(item, into: &buf)
2903+
}
2904+
}
2905+
2906+
public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [AmValue] {
2907+
let len: Int32 = try readInt(&buf)
2908+
var seq = [AmValue]()
2909+
seq.reserveCapacity(Int(len))
2910+
for _ in 0 ..< len {
2911+
try seq.append(FfiConverterTypeAMValue.read(from: &buf))
2912+
}
2913+
return seq
2914+
}
2915+
}
2916+
26882917
private struct FfiConverterSequenceTypeScalarValue: FfiConverterRustBuffer {
26892918
typealias SwiftType = [ScalarValue]
26902919

@@ -2751,6 +2980,29 @@ private struct FfiConverterSequenceTypeChangeHash: FfiConverterRustBuffer {
27512980
}
27522981
}
27532982

2983+
private struct FfiConverterDictionaryStringTypeAMValue: FfiConverterRustBuffer {
2984+
public static func write(_ value: [String: AmValue], into buf: inout [UInt8]) {
2985+
let len = Int32(value.count)
2986+
writeInt(&buf, len)
2987+
for (key, value) in value {
2988+
FfiConverterString.write(key, into: &buf)
2989+
FfiConverterTypeAMValue.write(value, into: &buf)
2990+
}
2991+
}
2992+
2993+
public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [String: AmValue] {
2994+
let len: Int32 = try readInt(&buf)
2995+
var dict = [String: AmValue]()
2996+
dict.reserveCapacity(Int(len))
2997+
for _ in 0 ..< len {
2998+
let key = try FfiConverterString.read(from: &buf)
2999+
let value = try FfiConverterTypeAMValue.read(from: &buf)
3000+
dict[key] = value
3001+
}
3002+
return dict
3003+
}
3004+
}
3005+
27543006
private struct FfiConverterDictionaryStringTypeValue: FfiConverterRustBuffer {
27553007
public static func write(_ value: [String: Value], into buf: inout [UInt8]) {
27563008
let len = Int32(value.count)
@@ -3018,6 +3270,9 @@ private var initializationResult: InitializationResult {
30183270
if uniffi_uniffi_automerge_checksum_method_doc_insert_object_in_list() != 30538 {
30193271
return InitializationResult.apiChecksumMismatch
30203272
}
3273+
if uniffi_uniffi_automerge_checksum_method_doc_join_block() != 37348 {
3274+
return InitializationResult.apiChecksumMismatch
3275+
}
30213276
if uniffi_uniffi_automerge_checksum_method_doc_length() != 30352 {
30223277
return InitializationResult.apiChecksumMismatch
30233278
}
@@ -3087,6 +3342,9 @@ private var initializationResult: InitializationResult {
30873342
if uniffi_uniffi_automerge_checksum_method_doc_splice_text() != 20602 {
30883343
return InitializationResult.apiChecksumMismatch
30893344
}
3345+
if uniffi_uniffi_automerge_checksum_method_doc_split_block() != 10956 {
3346+
return InitializationResult.apiChecksumMismatch
3347+
}
30903348
if uniffi_uniffi_automerge_checksum_method_doc_text() != 64716 {
30913349
return InitializationResult.apiChecksumMismatch
30923350
}

Sources/Automerge/Marks.swift

+8-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public struct Mark: Equatable, Hashable, Sendable {
1717
/// The name of the mark.
1818
public let name: String
1919
/// The value associated with the mark.
20-
public let value: Value
20+
public let value: ScalarValue
2121

2222
/// Creates a new mark.
2323
///
@@ -53,15 +53,20 @@ public struct Mark: Equatable, Hashable, Sendable {
5353
/// ```swift
5454
/// Int64("🇬🇧".unicodeScalars.count)
5555
/// ```
56-
public init(start: UInt64, end: UInt64, name: String, value: Value) {
56+
public init(start: UInt64, end: UInt64, name: String, value: ScalarValue) {
5757
self.start = start
5858
self.end = end
5959
self.name = name
6060
self.value = value
6161
}
6262

6363
static func fromFfi(_ ffiMark: FfiMark) -> Self {
64-
Self(start: ffiMark.start, end: ffiMark.end, name: ffiMark.name, value: Value.fromFfi(value: ffiMark.value))
64+
Self(
65+
start: ffiMark.start,
66+
end: ffiMark.end,
67+
name: ffiMark.name,
68+
value: ScalarValue.fromFfi(value: ffiMark.value)
69+
)
6570
}
6671
}
6772

0 commit comments

Comments
 (0)