---
source: boltffi_bindgen/src/render/swift/templates.rs
expression: render_callback(&callback)
---
/// > Warning: Callback methods may be invoked from any thread and the thread is not
/// > guaranteed to be the same between calls. Your implementation must be thread-safe.
/// > Dispatch to the main thread if updating UI.
public protocol Validator: AnyObject {
    func validate(input: String) -> Bool
}

private class ValidatorWrapper {
    let impl_: Validator
    init(_ impl_: Validator) { self.impl_ = impl_ }
}


private var validatorVtable: ValidatorVtable = {
    ValidatorVtable(
        free: { handle in
            guard handle != 0 else { return }
            Unmanaged<ValidatorWrapper>.fromOpaque(UnsafeRawPointer(bitPattern: UInt(handle))!).release()
        },
        clone: { handle in
            guard handle != 0 else { return 0 }
            let wrapper = Unmanaged<ValidatorWrapper>.fromOpaque(UnsafeRawPointer(bitPattern: UInt(handle))!)
            _ = wrapper.retain()
            return handle
        },
        validate: { handle, inputPtr, inputLen, outPtr, statusPtr in
            guard handle != 0 else { statusPtr?.pointee = FfiStatus(code: 1); return }
            let wrapper = Unmanaged<ValidatorWrapper>.fromOpaque(UnsafeRawPointer(bitPattern: UInt(handle))!).takeUnretainedValue()
            let input = String(decoding: UnsafeBufferPointer(start: inputPtr, count: Int(inputLen)), as: UTF8.self)
            let result = wrapper.impl_.validate(input: input)
            outPtr?.pointee = result
            statusPtr?.pointee = FfiStatus(code: 0)
        }
    )
}()

enum ValidatorBridge {
    private static let _register: Void = {
        boltffi_register_validator(&validatorVtable)
    }()

    static func create(_ impl: Validator) -> BoltFFICallbackHandle {
        _ = _register
        let wrapper = ValidatorWrapper(impl)
        let handle = UInt64(UInt(bitPattern: Unmanaged.passRetained(wrapper).toOpaque()))
        return boltffi_create_validator(handle)
    }
}
