Skip to content

Commit d5a12a4

Browse files
committed
Add cross-platform support for Linux, WASM and other platforms
1 parent e0ac81e commit d5a12a4

File tree

9 files changed

+155
-73
lines changed

9 files changed

+155
-73
lines changed

Sources/SwiftProtoReflect/Integration/StructHandler.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,21 @@ public struct StructHandler: WellKnownTypeHandler {
134134
self = .nullValue
135135
case let number as NSNumber:
136136
// NSNumber может представлять как Bool, так и Number
137+
#if canImport(CoreFoundation) && !os(Linux)
137138
if CFGetTypeID(number) == CFBooleanGetTypeID() {
138139
self = .boolValue(number.boolValue)
140+
} else {
141+
self = .numberValue(number.doubleValue)
139142
}
140-
else {
143+
#else
144+
// Cross-platform compatible way to detect boolean NSNumber on Linux
145+
let objCType = String(cString: number.objCType)
146+
if objCType == "c" || objCType == "B" { // char or Bool
147+
self = .boolValue(number.boolValue)
148+
} else {
141149
self = .numberValue(number.doubleValue)
142150
}
151+
#endif
143152
case let bool as Bool:
144153
self = .boolValue(bool)
145154
case let int as Int:

Sources/SwiftProtoReflect/Integration/TimestampHandler.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,20 @@ public struct TimestampHandler: WellKnownTypeHandler {
7474

7575
public var description: String {
7676
let date = toDate()
77+
78+
// Use cross-platform compatible date formatting
79+
#if canImport(Foundation) && !os(Linux)
7780
let formatter = ISO8601DateFormatter()
7881
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
7982
return formatter.string(from: date)
83+
#else
84+
// Fallback for Linux and other platforms
85+
let formatter = DateFormatter()
86+
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
87+
formatter.timeZone = TimeZone(identifier: "UTC")
88+
formatter.locale = Locale(identifier: "en_US_POSIX")
89+
return formatter.string(from: date)
90+
#endif
8091
}
8192

8293
// MARK: - Validation

Tests/SwiftProtoReflectTests/Descriptor/FieldDescriptorTests.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,13 +322,19 @@ final class FieldDescriptorTests: XCTestCase {
322322
func testInvalidKeyTypeForMap() {
323323
// Просто отметим, что создание MapEntryInfo с недопустимыми типами ключей должно вызывать ошибку
324324
// fatalError не использует throws, и мы не можем напрямую тестировать fatalError
325+
// XCTExpectFailure не доступна на Linux, поэтому просто отмечаем что тест ожидает сбой
326+
#if os(macOS) || os(iOS)
325327
XCTAssertNoThrow {
326328
XCTExpectFailure("MapEntryInfo с недопустимым типом ключа bytes должен вызвать ошибку")
327329
}
328330

329331
XCTAssertNoThrow {
330332
XCTExpectFailure("MapEntryInfo с недопустимым типом ключа double должен вызвать ошибку")
331333
}
334+
#else
335+
// На Linux пропускаем тесты с fatalError из-за отсутствия XCTExpectFailure
336+
print("Пропуск тестов fatalError на Linux (XCTExpectFailure недоступна)")
337+
#endif
332338
}
333339

334340
func testMapWithValueTypeMessage() {

examples/02-dynamic-messages/nested-operations.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -265,15 +265,15 @@ struct NestedOperationsExample {
265265
print("\n 🚀 Техники оптимизации производительности:")
266266

267267
// 1. Lazy traversal vs eager traversal
268-
let startTime1 = CFAbsoluteTimeGetCurrent()
269-
let lazyResult = try performLazyTraversal(tree)
270-
let lazyTime = CFAbsoluteTimeGetCurrent() - startTime1
268+
let (lazyResult, lazyTime) = try ExampleUtils.measureTime {
269+
return try performLazyTraversal(tree)
270+
}
271271
print(" 🐌 Ленивый обход: \(lazyResult) узлов за \(String(format: "%.4f", lazyTime))с")
272272

273273
// 2. Batch operations vs individual operations
274-
let startTime2 = CFAbsoluteTimeGetCurrent()
275-
let batchResult = try performBatchUpdates(tree)
276-
let batchTime = CFAbsoluteTimeGetCurrent() - startTime2
274+
let (batchResult, batchTime) = try ExampleUtils.measureTime {
275+
return try performBatchUpdates(tree)
276+
}
277277
print(" 📦 Batch обновления: \(batchResult) изменений за \(String(format: "%.4f", batchTime))с")
278278

279279
// 3. Memory-efficient operations

examples/02-dynamic-messages/performance-optimization.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -841,14 +841,12 @@ extension PerformanceOptimization {
841841

842842
// Performance measurement helper
843843
func measureMemoryAndTime<T>(_ operation: () throws -> T) throws -> (T, TimeInterval, Int) {
844-
let startTime = CFAbsoluteTimeGetCurrent()
845-
let result = try operation()
846-
let endTime = CFAbsoluteTimeGetCurrent()
844+
let (result, timeElapsed) = try ExampleUtils.measureTime(operation)
847845

848846
// Simulate memory measurement (in real app, use proper profiling tools)
849847
let simulatedMemoryUsage = Int.random(in: 10...50)
850848

851-
return (result, endTime - startTime, simulatedMemoryUsage)
849+
return (result, timeElapsed, simulatedMemoryUsage)
852850
}
853851

854852
// MARK: - Supporting Classes

examples/03-serialization/streaming.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020

2121
import ExampleUtils
2222
import Foundation
23+
#if canImport(OSLog)
2324
import OSLog
25+
#endif
2426
@preconcurrency import SwiftProtoReflect
2527

2628
@main
@@ -58,7 +60,11 @@ struct StreamingExample {
5860
let serializer = BinarySerializer()
5961

6062
// Streaming file for output
63+
#if canImport(Foundation) && !os(Linux)
6164
let tempDir = NSTemporaryDirectory()
65+
#else
66+
let tempDir = FileManager.default.temporaryDirectory.path + "/"
67+
#endif
6268
let streamingFile = "\(tempDir)streaming_records.bin"
6369
let outputStream = OutputStream(toFileAtPath: streamingFile, append: false)!
6470
outputStream.open()
@@ -136,7 +142,11 @@ struct StreamingExample {
136142
ExampleUtils.printStep(2, "Batch processing и deserialization")
137143

138144
// Read back the streaming file we created
145+
#if canImport(Foundation) && !os(Linux)
139146
let tempDir = NSTemporaryDirectory()
147+
#else
148+
let tempDir = FileManager.default.temporaryDirectory.path + "/"
149+
#endif
140150
let streamingFile = "\(tempDir)streaming_records.bin"
141151

142152
guard FileManager.default.fileExists(atPath: streamingFile) else {

0 commit comments

Comments
 (0)