diff --git a/Example/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Example/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index e227c65b8..545bf4c6f 100644 --- a/Example/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Example/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "34ec164994f4a7193f54a6829aeb133fff6d99ebe00bfbf67e2ac554c7ea9724", + "originHash" : "254d984aabc648722f4c902579675ea8e2c937654a313255c58df9d25e209369", "pins" : [ { "identity" : "equatable", @@ -10,24 +10,6 @@ "revision" : "8f1dccead65d97173ed695c6c1ba9d0570d35619" } }, - { - "identity" : "opencoregraphics", - "kind" : "remoteSourceControl", - "location" : "https://github.com/OpenSwiftUIProject/OpenCoreGraphics", - "state" : { - "branch" : "main", - "revision" : "8d63c405f565fb287042e0b8dc3bf0c4b8b2b56f" - } - }, - { - "identity" : "openobservation", - "kind" : "remoteSourceControl", - "location" : "https://github.com/OpenSwiftUIProject/OpenObservation", - "state" : { - "branch" : "main", - "revision" : "814dbe008056db6007bfc3d27fe585837f30e9ed" - } - }, { "identity" : "swift-custom-dump", "kind" : "remoteSourceControl", diff --git a/Example/SharedExample/ContentView.swift b/Example/SharedExample/ContentView.swift index 3695c64f4..68e8c215b 100644 --- a/Example/SharedExample/ContentView.swift +++ b/Example/SharedExample/ContentView.swift @@ -13,6 +13,6 @@ import SwiftUI struct ContentView: View { var body: some View { - FlowerView() + Image(systemName: "gear") } } diff --git a/Package.swift b/Package.swift index 84a1975d0..27af3e2c5 100644 --- a/Package.swift +++ b/Package.swift @@ -145,7 +145,7 @@ let releaseVersion = envIntValue("TARGET_RELEASE", default: 2024) let libraryEvolutionCondition = envBoolValue("LIBRARY_EVOLUTION", default: buildForDarwinPlatform) let compatibilityTestCondition = envBoolValue("COMPATIBILITY_TEST") -let useLocalDeps = envBoolValue("USE_LOCAL_DEPS") +let useLocalDeps = envBoolValue("USE_LOCAL_DEPS", default: true) // For OpenAttributeGraphShims let computeCondition = envBoolValue("OPENATTRIBUTESHIMS_COMPUTE", default: false) diff --git a/Sources/OpenSwiftUICore/Data/Protobuf/Foundation+ProtobufMessage.swift b/Sources/OpenSwiftUICore/Data/Protobuf/Foundation+ProtobufMessage.swift new file mode 100644 index 000000000..3c6b935ba --- /dev/null +++ b/Sources/OpenSwiftUICore/Data/Protobuf/Foundation+ProtobufMessage.swift @@ -0,0 +1,107 @@ +// +// Foundation+ProtobufMessage.swift +// OpenSwiftUICore +// +// Audited for 6.5.4 +// Status: WIP +// Note: Data archiveWriter/archiveReader deduplication not yet implemented + +package import Foundation + +// MARK: - URL + ProtobufMessage + +extension URL: ProtobufMessage { + package func encode(to encoder: inout ProtobufEncoder) throws { + try encoder.stringField(1, relativeString) + if let baseURL { + try encoder.messageField(2, baseURL) + } + } + + package init(from decoder: inout ProtobufDecoder) throws { + var relativeString = "" + var baseURL: URL? = nil + while let field = try decoder.nextField() { + switch field.tag { + case 1: relativeString = try decoder.stringField(field) + case 2: baseURL = try decoder.messageField(field) + default: try decoder.skipField(field) + } + } + guard let url = URL(string: relativeString, relativeTo: baseURL) else { + throw ProtobufDecoder.DecodingError.failed + } + self = url + } +} + +// MARK: - UUID + ProtobufMessage + +extension UUID: ProtobufMessage { + package func encode(to encoder: inout ProtobufEncoder) throws { + withUnsafeBytes(of: uuid) { buffer in + encoder.dataField(1, buffer) + } + } + + package init(from decoder: inout ProtobufDecoder) throws { + var uuidBytes: uuid_t = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + while let field = try decoder.nextField() { + switch field.tag { + case 1: + let buffer = try decoder.dataBufferField(field) + guard buffer.count == 16, let src = buffer.baseAddress else { + throw ProtobufDecoder.DecodingError.failed + } + withUnsafeMutableBytes(of: &uuidBytes) { $0.baseAddress!.copyMemory(from: src, byteCount: 16) } + default: + try decoder.skipField(field) + } + } + self = UUID(uuid: uuidBytes) + } +} + +// MARK: - Data + ProtobufMessage [WIP] + +extension Data: ProtobufMessage { + package func encode(to encoder: inout ProtobufEncoder) throws { + if /*let archiveWriter*/ false { + // TODO + _openSwiftUIUnreachableCode() + } else { + encoder.dataField(2, self) + } + } + + package init(from decoder: inout ProtobufDecoder) throws { + self = Data() + while let field = try decoder.nextField() { + switch field.tag { + case 2: + self = try decoder.dataField(field) + default: + try decoder.skipField(field) + } + } + } +} + +// MARK: - Locale + ProtobufMessage + +extension Locale: ProtobufMessage { + package func encode(to encoder: inout ProtobufEncoder) throws { + try encoder.stringField(1, identifier) + } + + package init(from decoder: inout ProtobufDecoder) throws { + var identifier = "" + while let field = try decoder.nextField() { + switch field.tag { + case 1: identifier = try decoder.stringField(field) + default: try decoder.skipField(field) + } + } + self = Locale(identifier: identifier) + } +} diff --git a/Sources/OpenSwiftUISymbolDualTestsSupport/Data/Protobuf/FoundationProtobufMessageTestsStub.c b/Sources/OpenSwiftUISymbolDualTestsSupport/Data/Protobuf/FoundationProtobufMessageTestsStub.c new file mode 100644 index 000000000..8a2476280 --- /dev/null +++ b/Sources/OpenSwiftUISymbolDualTestsSupport/Data/Protobuf/FoundationProtobufMessageTestsStub.c @@ -0,0 +1,26 @@ +// +// FoundationProtobufMessageTestsStub.c +// OpenSwiftUISymbolDualTestsSupport + +#include "OpenSwiftUIBase.h" + +#if OPENSWIFTUI_TARGET_OS_DARWIN +#import + +// URL +DEFINE_SL_STUB_SLF(OpenSwiftUITestStub_URLEncode, SwiftUICore, $s10Foundation3URLV7SwiftUIE6encode2toyAD15ProtobufEncoderVz_tKF); +DEFINE_SL_STUB_SLF(OpenSwiftUITestStub_URLDecode, SwiftUICore, $s10Foundation3URLV7SwiftUIE4fromAcD15ProtobufDecoderVz_tKcfC); + +// UUID +DEFINE_SL_STUB_SLF(OpenSwiftUITestStub_UUIDEncode, SwiftUICore, $s10Foundation4UUIDV7SwiftUIE6encode2toyAD15ProtobufEncoderVz_tKF); +DEFINE_SL_STUB_SLF(OpenSwiftUITestStub_UUIDDecode, SwiftUICore, $s10Foundation4UUIDV7SwiftUIE4fromAcD15ProtobufDecoderVz_tKcfC); + +// Data +DEFINE_SL_STUB_SLF(OpenSwiftUITestStub_DataEncode, SwiftUICore, $s10Foundation4DataV7SwiftUIE6encode2toyAD15ProtobufEncoderVz_tKF); +DEFINE_SL_STUB_SLF(OpenSwiftUITestStub_DataDecode, SwiftUICore, $s10Foundation4DataV7SwiftUIE4fromAcD15ProtobufDecoderVz_tKcfC); + +// Locale +DEFINE_SL_STUB_SLF(OpenSwiftUITestStub_LocaleEncode, SwiftUICore, $s10Foundation6LocaleV7SwiftUIE6encode2toyAD15ProtobufEncoderVz_tKF); +DEFINE_SL_STUB_SLF(OpenSwiftUITestStub_LocaleDecode, SwiftUICore, $s10Foundation6LocaleV7SwiftUIE4fromAcD15ProtobufDecoderVz_tKcfC); + +#endif diff --git a/Tests/OpenSwiftUISymbolDualTests/Data/Protobuf/FoundationProtobufMessageDualTests.swift b/Tests/OpenSwiftUISymbolDualTests/Data/Protobuf/FoundationProtobufMessageDualTests.swift new file mode 100644 index 000000000..73d2bd750 --- /dev/null +++ b/Tests/OpenSwiftUISymbolDualTests/Data/Protobuf/FoundationProtobufMessageDualTests.swift @@ -0,0 +1,196 @@ +// +// FoundationProtobufMessageDualTests.swift +// OpenSwiftUISymbolDualTests + +#if canImport(SwiftUI, _underlyingVersion: 6.5.4) +import Foundation +import OpenSwiftUICore +import OpenSwiftUITestsSupport +import Testing + +// MARK: - @_silgen_name declarations + +extension URL { + @_silgen_name("OpenSwiftUITestStub_URLEncode") + func swiftUI_encode(to encoder: inout ProtobufEncoder) throws + + @_silgen_name("OpenSwiftUITestStub_URLDecode") + init(swiftUI_from decoder: inout ProtobufDecoder) throws +} + +extension UUID { + @_silgen_name("OpenSwiftUITestStub_UUIDEncode") + func swiftUI_encode(to encoder: inout ProtobufEncoder) throws + + @_silgen_name("OpenSwiftUITestStub_UUIDDecode") + init(swiftUI_from decoder: inout ProtobufDecoder) throws +} + +extension Data { + @_silgen_name("OpenSwiftUITestStub_DataEncode") + func swiftUI_encode(to encoder: inout ProtobufEncoder) throws + + @_silgen_name("OpenSwiftUITestStub_DataDecode") + init(swiftUI_from decoder: inout ProtobufDecoder) throws +} + +extension Locale { + @_silgen_name("OpenSwiftUITestStub_LocaleEncode") + func swiftUI_encode(to encoder: inout ProtobufEncoder) throws + + @_silgen_name("OpenSwiftUITestStub_LocaleDecode") + init(swiftUI_from decoder: inout ProtobufDecoder) throws +} + +// MARK: - Tests + +@Suite +struct FoundationProtobufMessageDualTests { + @Suite + struct URLTests { + @Test( + arguments: [ + ( + URL(string: "https://example.com")!, + "0a1368747470733a2f2f6578616d706c652e636f6d" + ), + ( + URL(string: "path", relativeTo: URL(string: "https://example.com"))!, + "0a04706174681215 0a1368747470733a2f2f6578616d706c652e636f6d" + .replacingOccurrences(of: " ", with: "") + ), + ] + ) + func pbMessage(url: URL, hexString: String) throws { + try url.testPBEncoding(hexString: hexString) + try url.testPBDecoding(hexString: hexString) + try url.testPBEncoding(swiftUI_hexString: hexString) + try url.testPBDecoding(swiftUI_hexString: hexString) + } + } + + @Suite + struct UUIDTests { + @Test( + arguments: [ + ( + UUID(uuidString: "E621E1F8-C36C-495A-93FC-0C247A3E6E5F")!, + "0a10e621e1f8c36c495a93fc0c247a3e6e5f" + ), + ] + ) + func pbMessage(uuid: UUID, hexString: String) throws { + try uuid.testPBEncoding(hexString: hexString) + try uuid.testPBDecoding(hexString: hexString) + try uuid.testPBEncoding(swiftUI_hexString: hexString) + try uuid.testPBDecoding(swiftUI_hexString: hexString) + } + } + + @Suite + struct DataTests { + @Test( + arguments: [ + (Data(), ""), + (Data([0x48, 0x65, 0x6c, 0x6c, 0x6f]), "120548656c6c6f"), + ] + ) + func pbMessage(data: Data, hexString: String) throws { + try data.testPBEncoding(hexString: hexString) + try data.testPBDecoding(hexString: hexString) + try data.testPBEncoding(swiftUI_hexString: hexString) + try data.testPBDecoding(swiftUI_hexString: hexString) + } + } + + @Suite + struct LocaleTests { + @Test( + arguments: [ + (Locale(identifier: "en_US"), "0a05656e5f5553"), + ] + ) + func pbMessage(locale: Locale, hexString: String) throws { + try locale.testPBEncoding(hexString: hexString) + try locale.testPBDecoding(hexString: hexString) + try locale.testPBEncoding(swiftUI_hexString: hexString) + try locale.testPBDecoding(swiftUI_hexString: hexString) + } + } +} + +// MARK: - SwiftUI Dual Test Helpers + +extension URL { + func testPBEncoding(swiftUI_hexString expectedHexString: String) throws { + let data = try ProtobufEncoder.encoding { encoder in + try swiftUI_encode(to: &encoder) + } + #expect(data.hexString == expectedHexString) + } + + func testPBDecoding(swiftUI_hexString hexString: String) throws { + guard let data = Data(hexString: hexString) else { + throw ProtobufDecoder.DecodingError.failed + } + var decoder = ProtobufDecoder(data) + let decoded = try URL(swiftUI_from: &decoder) + #expect(decoded == self) + } +} + +extension UUID { + func testPBEncoding(swiftUI_hexString expectedHexString: String) throws { + let data = try ProtobufEncoder.encoding { encoder in + try swiftUI_encode(to: &encoder) + } + #expect(data.hexString == expectedHexString) + } + + func testPBDecoding(swiftUI_hexString hexString: String) throws { + guard let data = Data(hexString: hexString) else { + throw ProtobufDecoder.DecodingError.failed + } + var decoder = ProtobufDecoder(data) + let decoded = try UUID(swiftUI_from: &decoder) + #expect(decoded == self) + } +} + +extension Data { + func testPBEncoding(swiftUI_hexString expectedHexString: String) throws { + let data = try ProtobufEncoder.encoding { encoder in + try swiftUI_encode(to: &encoder) + } + #expect(data.hexString == expectedHexString) + } + + func testPBDecoding(swiftUI_hexString hexString: String) throws { + guard let data = Data(hexString: hexString) else { + throw ProtobufDecoder.DecodingError.failed + } + var decoder = ProtobufDecoder(data) + let decoded = try Data(swiftUI_from: &decoder) + #expect(decoded == self) + } +} + +extension Locale { + func testPBEncoding(swiftUI_hexString expectedHexString: String) throws { + let data = try ProtobufEncoder.encoding { encoder in + try swiftUI_encode(to: &encoder) + } + #expect(data.hexString == expectedHexString) + } + + func testPBDecoding(swiftUI_hexString hexString: String) throws { + guard let data = Data(hexString: hexString) else { + throw ProtobufDecoder.DecodingError.failed + } + var decoder = ProtobufDecoder(data) + let decoded = try Locale(swiftUI_from: &decoder) + #expect(decoded == self) + } +} + +#endif