This commit is contained in:
58
packages/swift/Sources/Kreuzberg/BridgeRegistrationOverloads.swift
generated
Normal file
58
packages/swift/Sources/Kreuzberg/BridgeRegistrationOverloads.swift
generated
Normal file
@@ -0,0 +1,58 @@
|
||||
// Generated by alef. Do not edit by hand.
|
||||
// swift-format-ignore-file
|
||||
// This file contains convenience overloads matching the alef e2e generator's call shapes.
|
||||
|
||||
import Foundation
|
||||
import RustBridge
|
||||
|
||||
// MARK: - Unregister name: label overloads
|
||||
|
||||
public func unregisterOcrBackend(name: String) throws {
|
||||
try RustBridge.unregisterOcrBackend(name)
|
||||
}
|
||||
|
||||
public func unregisterPostProcessor(name: String) throws {
|
||||
try RustBridge.unregisterPostProcessor(name)
|
||||
}
|
||||
|
||||
public func unregisterValidator(name: String) throws {
|
||||
try RustBridge.unregisterValidator(name)
|
||||
}
|
||||
|
||||
public func unregisterEmbeddingBackend(name: String) throws {
|
||||
try RustBridge.unregisterEmbeddingBackend(name)
|
||||
}
|
||||
|
||||
public func unregisterDocumentExtractor(name: String) throws {
|
||||
try RustBridge.unregisterDocumentExtractor(name)
|
||||
}
|
||||
|
||||
public func unregisterRenderer(name: String) throws {
|
||||
try RustBridge.unregisterRenderer(name)
|
||||
}
|
||||
|
||||
// MARK: - Bridge → Box register overloads
|
||||
|
||||
public func registerOcrBackend(_ bridge: any SwiftOcrBackendBridge) throws {
|
||||
try registerOcrBackend(SwiftOcrBackendBox(bridge))
|
||||
}
|
||||
|
||||
public func registerPostProcessor(_ bridge: any SwiftPostProcessorBridge) throws {
|
||||
try registerPostProcessor(SwiftPostProcessorBox(bridge))
|
||||
}
|
||||
|
||||
public func registerValidator(_ bridge: any SwiftValidatorBridge) throws {
|
||||
try registerValidator(SwiftValidatorBox(bridge))
|
||||
}
|
||||
|
||||
public func registerEmbeddingBackend(_ bridge: any SwiftEmbeddingBackendBridge) throws {
|
||||
try registerEmbeddingBackend(SwiftEmbeddingBackendBox(bridge))
|
||||
}
|
||||
|
||||
public func registerDocumentExtractor(_ bridge: any SwiftDocumentExtractorBridge) throws {
|
||||
try registerDocumentExtractor(SwiftDocumentExtractorBox(bridge))
|
||||
}
|
||||
|
||||
public func registerRenderer(_ bridge: any SwiftRendererBridge) throws {
|
||||
try registerRenderer(SwiftRendererBox(bridge))
|
||||
}
|
||||
20
packages/swift/Sources/Kreuzberg/ExtractionResultExtensions.swift
generated
Normal file
20
packages/swift/Sources/Kreuzberg/ExtractionResultExtensions.swift
generated
Normal file
@@ -0,0 +1,20 @@
|
||||
import RustBridge
|
||||
|
||||
// MARK: - Property-access ergonomics for e2e tests
|
||||
//
|
||||
// This file provides computed-property aliases for methods on swift-bridge-generated types,
|
||||
// allowing callers to write `result.mimeType` rather than `result.mimeType()`.
|
||||
// These extensions are especially useful in e2e test assertions where the alef
|
||||
// fixture generator emits property-access syntax.
|
||||
//
|
||||
// Although these are primarily for test convenience, they are part of the public API
|
||||
// and can be used in production code for more ergonomic access to extraction results.
|
||||
|
||||
extension RustBridge.ServerConfigRef {
|
||||
/// Computed-property alias for `listen_addr()` method.
|
||||
public var listen_addr: String {
|
||||
self.listen_addr().toString()
|
||||
}
|
||||
}
|
||||
|
||||
// ServerConfigRefMut and ServerConfig inherit the extensions automatically
|
||||
8477
packages/swift/Sources/Kreuzberg/Kreuzberg.swift
generated
Normal file
8477
packages/swift/Sources/Kreuzberg/Kreuzberg.swift
generated
Normal file
File diff suppressed because it is too large
Load Diff
93
packages/swift/Sources/Kreuzberg/LICENSE
generated
Normal file
93
packages/swift/Sources/Kreuzberg/LICENSE
generated
Normal file
@@ -0,0 +1,93 @@
|
||||
Elastic License 2.0 (ELv2)
|
||||
|
||||
Copyright 2025-2026 Kreuzberg, Inc.
|
||||
|
||||
Acceptance
|
||||
|
||||
By using the software, you agree to all of the terms and conditions below.
|
||||
|
||||
Copyright License
|
||||
|
||||
The licensor grants you a non-exclusive, royalty-free, worldwide,
|
||||
non-sublicensable, non-transferable license to use, copy, distribute, make
|
||||
available, and prepare derivative works of the software, in each case subject to
|
||||
the limitations and conditions below.
|
||||
|
||||
Limitations
|
||||
|
||||
You may not provide the software to third parties as a hosted or managed
|
||||
service, where the service provides users with access to any substantial set of
|
||||
the features or functionality of the software.
|
||||
|
||||
You may not move, change, disable, or circumvent the license key functionality
|
||||
in the software, and you may not remove or obscure any functionality in the
|
||||
software that is protected by the license key.
|
||||
|
||||
You may not alter, remove, or obscure any licensing, copyright, or other notices
|
||||
of the licensor in the software. Any use of the licensor's trademarks is subject
|
||||
to applicable law.
|
||||
|
||||
Patents
|
||||
|
||||
The licensor grants you a license, under any patent claims the licensor can
|
||||
license, or becomes able to license, to make, have made, use, sell, offer for
|
||||
sale, import and have imported the software, in each case subject to the
|
||||
limitations and conditions in this license. This license does not cover any
|
||||
patent claims that you cause to be infringed by modifications or additions to the
|
||||
software. If you or your company make any written claim that the software
|
||||
infringes or contributes to infringement of any patent, your patent license for
|
||||
the software granted under these terms ends immediately. If your company makes
|
||||
such a claim, your patent license ends immediately for work on behalf of your
|
||||
company.
|
||||
|
||||
Notices
|
||||
|
||||
You must ensure that anyone who gets a copy of any part of the software from you
|
||||
also gets a copy of these terms.
|
||||
|
||||
If you modify the software, you must include in any modified copies of the
|
||||
software prominent notices stating that you have modified the software.
|
||||
|
||||
No Other Rights
|
||||
|
||||
These terms do not imply any licenses other than those expressly granted in
|
||||
these terms.
|
||||
|
||||
Termination
|
||||
|
||||
If you use the software in violation of these terms, such use is not licensed,
|
||||
and your licenses will automatically terminate. If the licensor provides you with
|
||||
a notice of your violation, and you cease all violation of this license no later
|
||||
than 30 days after you receive that notice, your licenses will be reinstated
|
||||
retroactively. However, if you violate these terms after such reinstatement, any
|
||||
additional violation of these terms will cause your licenses to terminate
|
||||
automatically and permanently.
|
||||
|
||||
No Liability
|
||||
|
||||
As far as the law allows, the software comes as is, without any warranty or
|
||||
condition, and the licensor will not be liable to you for any damages arising out
|
||||
of these terms or the use or nature of the software, under any kind of legal
|
||||
claim.
|
||||
|
||||
Definitions
|
||||
|
||||
The licensor is the entity offering these terms, and the software is the
|
||||
software the licensor makes available under these terms, including any portion
|
||||
of it.
|
||||
|
||||
you refers to the individual or entity agreeing to these terms.
|
||||
|
||||
your company is any legal entity, sole proprietorship, or other kind of
|
||||
organization that you work for, plus all organizations that have control over,
|
||||
are under the control of, or are under common control with that organization.
|
||||
control means ownership of substantially all the assets of an entity, or the
|
||||
power to direct its management and policies by vote, contract, or otherwise.
|
||||
Control can be direct or indirect.
|
||||
|
||||
your licenses are all the licenses granted to you for the software under these
|
||||
terms.
|
||||
|
||||
use means anything you do with the software requiring one of your licenses.
|
||||
|
||||
trademark means trademarks, service marks, and similar rights.
|
||||
72
packages/swift/Sources/Kreuzberg/SwiftDocumentExtractorBridge.swift
generated
Normal file
72
packages/swift/Sources/Kreuzberg/SwiftDocumentExtractorBridge.swift
generated
Normal file
@@ -0,0 +1,72 @@
|
||||
// Generated by alef. Do not edit by hand.
|
||||
// swift-format-ignore-file
|
||||
// This file contains generated FFI glue for trait bridge registration.
|
||||
|
||||
import Foundation
|
||||
import RustBridge
|
||||
|
||||
/// Protocol for outbound `DocumentExtractor` implementations.
|
||||
/// Conform your Swift class or struct to this protocol to implement
|
||||
/// a Rust trait from the host side.
|
||||
public protocol SwiftDocumentExtractorBridge: AnyObject {
|
||||
func extractBytes(content: Data, mime_type: String, config: ExtractionConfig) throws -> String
|
||||
func supportedMimeTypes() -> [String]
|
||||
}
|
||||
|
||||
/// Internal adapter wrapping a `SwiftDocumentExtractorBridge` conformer.
|
||||
/// Marshals Swift types and trait calls to/from the C boundary.
|
||||
/// Excluded/internal types are serialised to/from JSON strings.
|
||||
final class SwiftDocumentExtractorAdapter {
|
||||
private let bridge: any SwiftDocumentExtractorBridge
|
||||
|
||||
init(bridge: any SwiftDocumentExtractorBridge) {
|
||||
self.bridge = bridge
|
||||
}
|
||||
|
||||
func extractBytesCall(content: Data, mime_type: String, config: ExtractionConfig) throws -> String {
|
||||
do {
|
||||
let result = try self.bridge.extractBytes(content: content, mime_type: mime_type, config: config)
|
||||
let encodedData = try marshal_encode_excluded(result)
|
||||
if let jsonString = String(data: encodedData, encoding: .utf8) {
|
||||
return "{\"ok\": \(jsonString)}"
|
||||
}
|
||||
return "{\"ok\": null}"
|
||||
} catch {
|
||||
return marshal_error_result(error)
|
||||
}
|
||||
}
|
||||
|
||||
func supportedMimeTypesCall() -> [String] {
|
||||
let result = self.bridge.supportedMimeTypes()
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Marshalling helpers
|
||||
|
||||
private struct Empty: Codable {}
|
||||
|
||||
private func marshal_ok_result<T: Encodable>(_ value: T) -> String {
|
||||
let encoder = JSONEncoder()
|
||||
if let data = try? encoder.encode(value),
|
||||
let jsonString = String(data: data, encoding: .utf8) {
|
||||
return "{\"ok\": \(jsonString)}"
|
||||
}
|
||||
return "{\"ok\": null}"
|
||||
}
|
||||
|
||||
private func marshal_encode_excluded<T: Encodable>(_ value: T) throws -> Data {
|
||||
let encoder = JSONEncoder()
|
||||
return try encoder.encode(value)
|
||||
}
|
||||
|
||||
private func marshal_error_result(_ error: any Error) -> String {
|
||||
let errorString = String(describing: error)
|
||||
let encoder = JSONEncoder()
|
||||
if let data = try? encoder.encode(errorString),
|
||||
let jsonString = String(data: data, encoding: .utf8) {
|
||||
return "{\"err\": \(jsonString)}"
|
||||
}
|
||||
return "{\"err\": \"unknown error\"}"
|
||||
}
|
||||
68
packages/swift/Sources/Kreuzberg/SwiftEmbeddingBackendBridge.swift
generated
Normal file
68
packages/swift/Sources/Kreuzberg/SwiftEmbeddingBackendBridge.swift
generated
Normal file
@@ -0,0 +1,68 @@
|
||||
// Generated by alef. Do not edit by hand.
|
||||
// swift-format-ignore-file
|
||||
// This file contains generated FFI glue for trait bridge registration.
|
||||
|
||||
import Foundation
|
||||
import RustBridge
|
||||
|
||||
/// Protocol for outbound `EmbeddingBackend` implementations.
|
||||
/// Conform your Swift class or struct to this protocol to implement
|
||||
/// a Rust trait from the host side.
|
||||
public protocol SwiftEmbeddingBackendBridge: AnyObject {
|
||||
func dimensions() -> Int
|
||||
func embed(texts: [String]) throws -> [[Float]]
|
||||
}
|
||||
|
||||
/// Internal adapter wrapping a `SwiftEmbeddingBackendBridge` conformer.
|
||||
/// Marshals Swift types and trait calls to/from the C boundary.
|
||||
/// Excluded/internal types are serialised to/from JSON strings.
|
||||
final class SwiftEmbeddingBackendAdapter {
|
||||
private let bridge: any SwiftEmbeddingBackendBridge
|
||||
|
||||
init(bridge: any SwiftEmbeddingBackendBridge) {
|
||||
self.bridge = bridge
|
||||
}
|
||||
|
||||
func dimensionsCall() -> Int {
|
||||
let result = self.bridge.dimensions()
|
||||
return result
|
||||
}
|
||||
|
||||
func embedCall(texts: [String]) throws -> String {
|
||||
do {
|
||||
let result = try self.bridge.embed(texts: texts)
|
||||
return marshal_ok_result(try JSONEncoder().encode(result))
|
||||
} catch {
|
||||
return marshal_error_result(error)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Marshalling helpers
|
||||
|
||||
private struct Empty: Codable {}
|
||||
|
||||
private func marshal_ok_result<T: Encodable>(_ value: T) -> String {
|
||||
let encoder = JSONEncoder()
|
||||
if let data = try? encoder.encode(value),
|
||||
let jsonString = String(data: data, encoding: .utf8) {
|
||||
return "{\"ok\": \(jsonString)}"
|
||||
}
|
||||
return "{\"ok\": null}"
|
||||
}
|
||||
|
||||
private func marshal_encode_excluded<T: Encodable>(_ value: T) throws -> Data {
|
||||
let encoder = JSONEncoder()
|
||||
return try encoder.encode(value)
|
||||
}
|
||||
|
||||
private func marshal_error_result(_ error: any Error) -> String {
|
||||
let errorString = String(describing: error)
|
||||
let encoder = JSONEncoder()
|
||||
if let data = try? encoder.encode(errorString),
|
||||
let jsonString = String(data: data, encoding: .utf8) {
|
||||
return "{\"err\": \(jsonString)}"
|
||||
}
|
||||
return "{\"err\": \"unknown error\"}"
|
||||
}
|
||||
78
packages/swift/Sources/Kreuzberg/SwiftOcrBackendBridge.swift
generated
Normal file
78
packages/swift/Sources/Kreuzberg/SwiftOcrBackendBridge.swift
generated
Normal file
@@ -0,0 +1,78 @@
|
||||
// Generated by alef. Do not edit by hand.
|
||||
// swift-format-ignore-file
|
||||
// This file contains generated FFI glue for trait bridge registration.
|
||||
|
||||
import Foundation
|
||||
import RustBridge
|
||||
|
||||
/// Protocol for outbound `OcrBackend` implementations.
|
||||
/// Conform your Swift class or struct to this protocol to implement
|
||||
/// a Rust trait from the host side.
|
||||
public protocol SwiftOcrBackendBridge: AnyObject {
|
||||
func processImage(image_bytes: Data, config: OcrConfig) throws -> String
|
||||
func supportsLanguage(lang: String) -> Bool
|
||||
func backendType() -> OcrBackendType
|
||||
}
|
||||
|
||||
/// Internal adapter wrapping a `SwiftOcrBackendBridge` conformer.
|
||||
/// Marshals Swift types and trait calls to/from the C boundary.
|
||||
/// Excluded/internal types are serialised to/from JSON strings.
|
||||
final class SwiftOcrBackendAdapter {
|
||||
private let bridge: any SwiftOcrBackendBridge
|
||||
|
||||
init(bridge: any SwiftOcrBackendBridge) {
|
||||
self.bridge = bridge
|
||||
}
|
||||
|
||||
func processImageCall(image_bytes: Data, config: OcrConfig) throws -> String {
|
||||
do {
|
||||
let result = try self.bridge.processImage(image_bytes: image_bytes, config: config)
|
||||
let encodedData = try marshal_encode_excluded(result)
|
||||
if let jsonString = String(data: encodedData, encoding: .utf8) {
|
||||
return "{\"ok\": \(jsonString)}"
|
||||
}
|
||||
return "{\"ok\": null}"
|
||||
} catch {
|
||||
return marshal_error_result(error)
|
||||
}
|
||||
}
|
||||
|
||||
func supportsLanguageCall(lang: String) -> Bool {
|
||||
let result = self.bridge.supportsLanguage(lang: lang)
|
||||
return result
|
||||
}
|
||||
|
||||
func backendTypeCall() -> OcrBackendType {
|
||||
let result = self.bridge.backendType()
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Marshalling helpers
|
||||
|
||||
private struct Empty: Codable {}
|
||||
|
||||
private func marshal_ok_result<T: Encodable>(_ value: T) -> String {
|
||||
let encoder = JSONEncoder()
|
||||
if let data = try? encoder.encode(value),
|
||||
let jsonString = String(data: data, encoding: .utf8) {
|
||||
return "{\"ok\": \(jsonString)}"
|
||||
}
|
||||
return "{\"ok\": null}"
|
||||
}
|
||||
|
||||
private func marshal_encode_excluded<T: Encodable>(_ value: T) throws -> Data {
|
||||
let encoder = JSONEncoder()
|
||||
return try encoder.encode(value)
|
||||
}
|
||||
|
||||
private func marshal_error_result(_ error: any Error) -> String {
|
||||
let errorString = String(describing: error)
|
||||
let encoder = JSONEncoder()
|
||||
if let data = try? encoder.encode(errorString),
|
||||
let jsonString = String(data: data, encoding: .utf8) {
|
||||
return "{\"err\": \(jsonString)}"
|
||||
}
|
||||
return "{\"err\": \"unknown error\"}"
|
||||
}
|
||||
68
packages/swift/Sources/Kreuzberg/SwiftPostProcessorBridge.swift
generated
Normal file
68
packages/swift/Sources/Kreuzberg/SwiftPostProcessorBridge.swift
generated
Normal file
@@ -0,0 +1,68 @@
|
||||
// Generated by alef. Do not edit by hand.
|
||||
// swift-format-ignore-file
|
||||
// This file contains generated FFI glue for trait bridge registration.
|
||||
|
||||
import Foundation
|
||||
import RustBridge
|
||||
|
||||
/// Protocol for outbound `PostProcessor` implementations.
|
||||
/// Conform your Swift class or struct to this protocol to implement
|
||||
/// a Rust trait from the host side.
|
||||
public protocol SwiftPostProcessorBridge: AnyObject {
|
||||
func process(result: String, config: ExtractionConfig) throws -> Void
|
||||
func processingStage() -> ProcessingStage
|
||||
}
|
||||
|
||||
/// Internal adapter wrapping a `SwiftPostProcessorBridge` conformer.
|
||||
/// Marshals Swift types and trait calls to/from the C boundary.
|
||||
/// Excluded/internal types are serialised to/from JSON strings.
|
||||
final class SwiftPostProcessorAdapter {
|
||||
private let bridge: any SwiftPostProcessorBridge
|
||||
|
||||
init(bridge: any SwiftPostProcessorBridge) {
|
||||
self.bridge = bridge
|
||||
}
|
||||
|
||||
func processCall(result: String, config: ExtractionConfig) throws -> String {
|
||||
do {
|
||||
let result = try self.bridge.process(result: result, config: config)
|
||||
return marshal_ok_result(Empty())
|
||||
} catch {
|
||||
return marshal_error_result(error)
|
||||
}
|
||||
}
|
||||
|
||||
func processingStageCall() -> ProcessingStage {
|
||||
let result = self.bridge.processingStage()
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Marshalling helpers
|
||||
|
||||
private struct Empty: Codable {}
|
||||
|
||||
private func marshal_ok_result<T: Encodable>(_ value: T) -> String {
|
||||
let encoder = JSONEncoder()
|
||||
if let data = try? encoder.encode(value),
|
||||
let jsonString = String(data: data, encoding: .utf8) {
|
||||
return "{\"ok\": \(jsonString)}"
|
||||
}
|
||||
return "{\"ok\": null}"
|
||||
}
|
||||
|
||||
private func marshal_encode_excluded<T: Encodable>(_ value: T) throws -> Data {
|
||||
let encoder = JSONEncoder()
|
||||
return try encoder.encode(value)
|
||||
}
|
||||
|
||||
private func marshal_error_result(_ error: any Error) -> String {
|
||||
let errorString = String(describing: error)
|
||||
let encoder = JSONEncoder()
|
||||
if let data = try? encoder.encode(errorString),
|
||||
let jsonString = String(data: data, encoding: .utf8) {
|
||||
return "{\"err\": \(jsonString)}"
|
||||
}
|
||||
return "{\"err\": \"unknown error\"}"
|
||||
}
|
||||
62
packages/swift/Sources/Kreuzberg/SwiftRendererBridge.swift
generated
Normal file
62
packages/swift/Sources/Kreuzberg/SwiftRendererBridge.swift
generated
Normal file
@@ -0,0 +1,62 @@
|
||||
// Generated by alef. Do not edit by hand.
|
||||
// swift-format-ignore-file
|
||||
// This file contains generated FFI glue for trait bridge registration.
|
||||
|
||||
import Foundation
|
||||
import RustBridge
|
||||
|
||||
/// Protocol for outbound `Renderer` implementations.
|
||||
/// Conform your Swift class or struct to this protocol to implement
|
||||
/// a Rust trait from the host side.
|
||||
public protocol SwiftRendererBridge: AnyObject {
|
||||
func render(doc: String) throws -> String
|
||||
}
|
||||
|
||||
/// Internal adapter wrapping a `SwiftRendererBridge` conformer.
|
||||
/// Marshals Swift types and trait calls to/from the C boundary.
|
||||
/// Excluded/internal types are serialised to/from JSON strings.
|
||||
final class SwiftRendererAdapter {
|
||||
private let bridge: any SwiftRendererBridge
|
||||
|
||||
init(bridge: any SwiftRendererBridge) {
|
||||
self.bridge = bridge
|
||||
}
|
||||
|
||||
func renderCall(doc: String) throws -> String {
|
||||
do {
|
||||
let result = try self.bridge.render(doc: doc)
|
||||
return marshal_ok_result(result)
|
||||
} catch {
|
||||
return marshal_error_result(error)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Marshalling helpers
|
||||
|
||||
private struct Empty: Codable {}
|
||||
|
||||
private func marshal_ok_result<T: Encodable>(_ value: T) -> String {
|
||||
let encoder = JSONEncoder()
|
||||
if let data = try? encoder.encode(value),
|
||||
let jsonString = String(data: data, encoding: .utf8) {
|
||||
return "{\"ok\": \(jsonString)}"
|
||||
}
|
||||
return "{\"ok\": null}"
|
||||
}
|
||||
|
||||
private func marshal_encode_excluded<T: Encodable>(_ value: T) throws -> Data {
|
||||
let encoder = JSONEncoder()
|
||||
return try encoder.encode(value)
|
||||
}
|
||||
|
||||
private func marshal_error_result(_ error: any Error) -> String {
|
||||
let errorString = String(describing: error)
|
||||
let encoder = JSONEncoder()
|
||||
if let data = try? encoder.encode(errorString),
|
||||
let jsonString = String(data: data, encoding: .utf8) {
|
||||
return "{\"err\": \(jsonString)}"
|
||||
}
|
||||
return "{\"err\": \"unknown error\"}"
|
||||
}
|
||||
62
packages/swift/Sources/Kreuzberg/SwiftValidatorBridge.swift
generated
Normal file
62
packages/swift/Sources/Kreuzberg/SwiftValidatorBridge.swift
generated
Normal file
@@ -0,0 +1,62 @@
|
||||
// Generated by alef. Do not edit by hand.
|
||||
// swift-format-ignore-file
|
||||
// This file contains generated FFI glue for trait bridge registration.
|
||||
|
||||
import Foundation
|
||||
import RustBridge
|
||||
|
||||
/// Protocol for outbound `Validator` implementations.
|
||||
/// Conform your Swift class or struct to this protocol to implement
|
||||
/// a Rust trait from the host side.
|
||||
public protocol SwiftValidatorBridge: AnyObject {
|
||||
func validate(result: String, config: ExtractionConfig) throws -> Void
|
||||
}
|
||||
|
||||
/// Internal adapter wrapping a `SwiftValidatorBridge` conformer.
|
||||
/// Marshals Swift types and trait calls to/from the C boundary.
|
||||
/// Excluded/internal types are serialised to/from JSON strings.
|
||||
final class SwiftValidatorAdapter {
|
||||
private let bridge: any SwiftValidatorBridge
|
||||
|
||||
init(bridge: any SwiftValidatorBridge) {
|
||||
self.bridge = bridge
|
||||
}
|
||||
|
||||
func validateCall(result: String, config: ExtractionConfig) throws -> String {
|
||||
do {
|
||||
let result = try self.bridge.validate(result: result, config: config)
|
||||
return marshal_ok_result(Empty())
|
||||
} catch {
|
||||
return marshal_error_result(error)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Marshalling helpers
|
||||
|
||||
private struct Empty: Codable {}
|
||||
|
||||
private func marshal_ok_result<T: Encodable>(_ value: T) -> String {
|
||||
let encoder = JSONEncoder()
|
||||
if let data = try? encoder.encode(value),
|
||||
let jsonString = String(data: data, encoding: .utf8) {
|
||||
return "{\"ok\": \(jsonString)}"
|
||||
}
|
||||
return "{\"ok\": null}"
|
||||
}
|
||||
|
||||
private func marshal_encode_excluded<T: Encodable>(_ value: T) throws -> Data {
|
||||
let encoder = JSONEncoder()
|
||||
return try encoder.encode(value)
|
||||
}
|
||||
|
||||
private func marshal_error_result(_ error: any Error) -> String {
|
||||
let errorString = String(describing: error)
|
||||
let encoder = JSONEncoder()
|
||||
if let data = try? encoder.encode(errorString),
|
||||
let jsonString = String(data: data, encoding: .utf8) {
|
||||
return "{\"err\": \(jsonString)}"
|
||||
}
|
||||
return "{\"err\": \"unknown error\"}"
|
||||
}
|
||||
Reference in New Issue
Block a user