Files
fil/packages/go/v5/trait_bridges.go
Henrik Jess Nielsen b4c07d3693
All checks were successful
Deploy fil (kreuzberg) / deploy (push) Successful in 49s
Nomad changes
2026-06-01 23:40:55 +02:00

1988 lines
50 KiB
Go
Generated

// This file is auto-generated by alef — DO NOT EDIT.
// alef:hash:4e15143f4af1ae8bafbdb1506ef057da924484c66a19483966333558ad437e75
// To regenerate: alef generate
// To verify freshness: alef verify --exit-code
// Issues & docs: https://github.com/kreuzberg-dev/alef
package kreuzberg
/*
#cgo CFLAGS: -I${SRCDIR}/include
#include "kreuzberg.h"
#include <stdlib.h>
#include <string.h>
extern int32_t goOcrBackendProcessImage(void* user_data, uint8_t* image_bytes, size_t image_bytes_len, char* config, char** out_result, char** out_error);
extern int32_t goOcrBackendProcessImageFile(void* user_data, char* path, char* config, char** out_result, char** out_error);
extern int32_t goOcrBackendSupportsLanguage(void* user_data, char* lang, char** out_result, char** out_error);
extern int32_t goOcrBackendBackendType(void* user_data, char** out_result, char** out_error);
extern int32_t goOcrBackendSupportedLanguages(void* user_data, char** out_result, char** out_error);
extern int32_t goOcrBackendSupportsTableDetection(void* user_data, char** out_result, char** out_error);
extern int32_t goOcrBackendSupportsDocumentProcessing(void* user_data, char** out_result, char** out_error);
extern int32_t goOcrBackendProcessDocument(void* user_data, char* _path, char* _config, char** out_result, char** out_error);
extern int32_t goOcrBackendName(void*, char**, char**);
extern int32_t goOcrBackendVersion(void*, char**, char**);
extern int32_t goOcrBackendInitialize(void*, char**);
extern int32_t goOcrBackendShutdown(void*, char**);
extern void goOcrBackendFreeUserData(void*);
extern void goOcrBackendFreeString(char*);
extern int32_t goPostProcessorProcess(void* user_data, char* result, char* config, char** out_error);
extern int32_t goPostProcessorProcessingStage(void* user_data, char** out_result, char** out_error);
extern int32_t goPostProcessorShouldProcess(void* user_data, char* _result, char* _config, char** out_result, char** out_error);
extern int32_t goPostProcessorEstimatedDurationMs(void* user_data, char* _result, char** out_result, char** out_error);
extern int32_t goPostProcessorPriority(void* user_data, char** out_result, char** out_error);
extern int32_t goPostProcessorName(void*, char**, char**);
extern int32_t goPostProcessorVersion(void*, char**, char**);
extern int32_t goPostProcessorInitialize(void*, char**);
extern int32_t goPostProcessorShutdown(void*, char**);
extern void goPostProcessorFreeUserData(void*);
extern void goPostProcessorFreeString(char*);
extern int32_t goValidatorValidate(void* user_data, char* result, char* config, char** out_error);
extern int32_t goValidatorShouldValidate(void* user_data, char* _result, char* _config, char** out_result, char** out_error);
extern int32_t goValidatorPriority(void* user_data, char** out_result, char** out_error);
extern int32_t goValidatorName(void*, char**, char**);
extern int32_t goValidatorVersion(void*, char**, char**);
extern int32_t goValidatorInitialize(void*, char**);
extern int32_t goValidatorShutdown(void*, char**);
extern void goValidatorFreeUserData(void*);
extern void goValidatorFreeString(char*);
extern int32_t goEmbeddingBackendDimensions(void* user_data, char** out_result, char** out_error);
extern int32_t goEmbeddingBackendEmbed(void* user_data, char* texts, char** out_result, char** out_error);
extern int32_t goEmbeddingBackendName(void*, char**, char**);
extern int32_t goEmbeddingBackendVersion(void*, char**, char**);
extern int32_t goEmbeddingBackendInitialize(void*, char**);
extern int32_t goEmbeddingBackendShutdown(void*, char**);
extern void goEmbeddingBackendFreeUserData(void*);
extern void goEmbeddingBackendFreeString(char*);
extern int32_t goDocumentExtractorExtractBytes(void* user_data, uint8_t* content, size_t content_len, char* mime_type, char* config, char** out_result, char** out_error);
extern int32_t goDocumentExtractorExtractFile(void* user_data, char* path, char* mime_type, char* config, char** out_result, char** out_error);
extern int32_t goDocumentExtractorSupportedMimeTypes(void* user_data, char** out_result, char** out_error);
extern int32_t goDocumentExtractorPriority(void* user_data, char** out_result, char** out_error);
extern int32_t goDocumentExtractorCanHandle(void* user_data, char* _path, char* _mime_type, char** out_result, char** out_error);
extern int32_t goDocumentExtractorName(void*, char**, char**);
extern int32_t goDocumentExtractorVersion(void*, char**, char**);
extern int32_t goDocumentExtractorInitialize(void*, char**);
extern int32_t goDocumentExtractorShutdown(void*, char**);
extern void goDocumentExtractorFreeUserData(void*);
extern void goDocumentExtractorFreeString(char*);
extern int32_t goRendererRender(void* user_data, char* doc, char** out_result, char** out_error);
extern int32_t goRendererName(void*, char**, char**);
extern int32_t goRendererVersion(void*, char**, char**);
extern int32_t goRendererInitialize(void*, char**);
extern int32_t goRendererShutdown(void*, char**);
extern void goRendererFreeUserData(void*);
extern void goRendererFreeString(char*);
*/
import "C"
import (
"encoding/json"
"fmt"
"runtime/cgo"
"sync"
"unsafe"
)
// handleRegistry tracks cgo.Handles by name to ensure proper cleanup on unregister.
// Without this, unregistered plugins can cause use-after-free crashes when Rust
// still holds vtable pointers and tries to invoke callbacks on deleted handles.
type handleRegistry struct {
mu sync.Mutex
handles map[string]cgo.Handle
}
var (
ocr_backendRegistry = &handleRegistry{handles: make(map[string]cgo.Handle)}
post_processorRegistry = &handleRegistry{handles: make(map[string]cgo.Handle)}
validatorRegistry = &handleRegistry{handles: make(map[string]cgo.Handle)}
embedding_backendRegistry = &handleRegistry{handles: make(map[string]cgo.Handle)}
document_extractorRegistry = &handleRegistry{handles: make(map[string]cgo.Handle)}
rendererRegistry = &handleRegistry{handles: make(map[string]cgo.Handle)}
)
// store adds a handle to the registry, keyed by name.
func (reg *handleRegistry) store(name string, handle cgo.Handle) {
reg.mu.Lock()
defer reg.mu.Unlock()
if old, ok := reg.handles[name]; ok {
old.Delete()
}
reg.handles[name] = handle
}
// delete removes and deletes a handle from the registry by name.
func (reg *handleRegistry) delete(name string) {
reg.mu.Lock()
defer reg.mu.Unlock()
if handle, ok := reg.handles[name]; ok {
delete(reg.handles, name)
handle.Delete()
}
}
// clear removes and deletes all handles from the registry.
func (reg *handleRegistry) clear() {
reg.mu.Lock()
defer reg.mu.Unlock()
for _, handle := range reg.handles {
handle.Delete()
}
reg.handles = make(map[string]cgo.Handle)
}
// OcrBackend defines the Go interface for the OcrBackend trait.
type OcrBackend interface {
// Name returns the plugin name.
Name() string
// Version returns the plugin version.
Version() string
// Initialize is called when the plugin is loaded.
Initialize() error
// Shutdown is called when the plugin is unloaded.
Shutdown() error
// process_image
ProcessImage(image_bytes []byte, config OcrConfig) (ExtractionResult, error)
// process_image_file
ProcessImageFile(path string, config OcrConfig) (ExtractionResult, error)
// supports_language
SupportsLanguage(lang string) bool
// backend_type
BackendType() OcrBackendType
// supported_languages
SupportedLanguages() []string
// supports_table_detection
SupportsTableDetection() bool
// supports_document_processing
SupportsDocumentProcessing() bool
// process_document
ProcessDocument(_path string, _config OcrConfig) (ExtractionResult, error)
}
//export goOcrBackendProcessImage
func goOcrBackendProcessImage(
userData unsafe.Pointer,
image_bytes *C.uint8_t,
image_bytesLen C.size_t,
config *C.char,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(OcrBackend)
if !ok {
return 1 // error: invalid handle
}
var goImage_bytes []byte
if image_bytes != nil {
goImage_bytes = unsafe.Slice((*byte)(unsafe.Pointer(image_bytes)), int(image_bytesLen))
}
var goConfig OcrConfig
if config != nil {
json.Unmarshal([]byte(C.GoString(config)), &goConfig)
}
// Call the method
result, err := impl.ProcessImage(goImage_bytes, goConfig)
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
jsonBytes, _ := json.Marshal(result)
cResult := C.CString(string(jsonBytes))
*outResult = cResult
return 0 // success
}
//export goOcrBackendProcessImageFile
func goOcrBackendProcessImageFile(
userData unsafe.Pointer,
path *C.char,
config *C.char,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(OcrBackend)
if !ok {
return 1 // error: invalid handle
}
goPath := C.GoString(path)
var goConfig OcrConfig
if config != nil {
json.Unmarshal([]byte(C.GoString(config)), &goConfig)
}
// Call the method
result, err := impl.ProcessImageFile(goPath, goConfig)
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
jsonBytes, _ := json.Marshal(result)
cResult := C.CString(string(jsonBytes))
*outResult = cResult
return 0 // success
}
//export goOcrBackendSupportsLanguage
func goOcrBackendSupportsLanguage(
userData unsafe.Pointer,
lang *C.char,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(OcrBackend)
if !ok {
return 1 // error: invalid handle
}
goLang := C.GoString(lang)
// Call the method
result := impl.SupportsLanguage(goLang)
jsonBytes, _ := json.Marshal(result)
cResult := C.CString(string(jsonBytes))
*outResult = cResult
return 0 // success
}
//export goOcrBackendBackendType
func goOcrBackendBackendType(
userData unsafe.Pointer,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(OcrBackend)
if !ok {
return 1 // error: invalid handle
}
// Call the method
result := impl.BackendType()
jsonBytes, _ := json.Marshal(result)
cResult := C.CString(string(jsonBytes))
*outResult = cResult
return 0 // success
}
//export goOcrBackendSupportedLanguages
func goOcrBackendSupportedLanguages(
userData unsafe.Pointer,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(OcrBackend)
if !ok {
return 1 // error: invalid handle
}
// Call the method
result := impl.SupportedLanguages()
jsonBytes, _ := json.Marshal(result)
cResult := C.CString(string(jsonBytes))
*outResult = cResult
return 0 // success
}
//export goOcrBackendSupportsTableDetection
func goOcrBackendSupportsTableDetection(
userData unsafe.Pointer,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(OcrBackend)
if !ok {
return 1 // error: invalid handle
}
// Call the method
result := impl.SupportsTableDetection()
jsonBytes, _ := json.Marshal(result)
cResult := C.CString(string(jsonBytes))
*outResult = cResult
return 0 // success
}
//export goOcrBackendSupportsDocumentProcessing
func goOcrBackendSupportsDocumentProcessing(
userData unsafe.Pointer,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(OcrBackend)
if !ok {
return 1 // error: invalid handle
}
// Call the method
result := impl.SupportsDocumentProcessing()
jsonBytes, _ := json.Marshal(result)
cResult := C.CString(string(jsonBytes))
*outResult = cResult
return 0 // success
}
//export goOcrBackendProcessDocument
func goOcrBackendProcessDocument(
userData unsafe.Pointer,
_path *C.char,
_config *C.char,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(OcrBackend)
if !ok {
return 1 // error: invalid handle
}
go_path := C.GoString(_path)
var go_config OcrConfig
if _config != nil {
json.Unmarshal([]byte(C.GoString(_config)), &go_config)
}
// Call the method
result, err := impl.ProcessDocument(go_path, go_config)
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
jsonBytes, _ := json.Marshal(result)
cResult := C.CString(string(jsonBytes))
*outResult = cResult
return 0 // success
}
//export goOcrBackendName
func goOcrBackendName(userData unsafe.Pointer, outResult **C.char, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(OcrBackend)
if !ok {
return 1
}
name := impl.Name()
cName := C.CString(name)
*outResult = cName
return 0
}
//export goOcrBackendVersion
func goOcrBackendVersion(userData unsafe.Pointer, outResult **C.char, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(OcrBackend)
if !ok {
return 1
}
version := impl.Version()
cVersion := C.CString(version)
*outResult = cVersion
return 0
}
//export goOcrBackendInitialize
func goOcrBackendInitialize(userData unsafe.Pointer, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(OcrBackend)
if !ok {
return 1
}
err := impl.Initialize()
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
return 0
}
//export goOcrBackendShutdown
func goOcrBackendShutdown(userData unsafe.Pointer, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(OcrBackend)
if !ok {
return 1
}
err := impl.Shutdown()
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
return 0
}
//export goOcrBackendFreeUserData
func goOcrBackendFreeUserData(userData unsafe.Pointer) {
// No-op to avoid cleanup-queue panics. Handles cleaned in Unregister().
}
//export goOcrBackendFreeString
func goOcrBackendFreeString(ptr *C.char) {
if ptr != nil {
C.free(unsafe.Pointer(ptr))
}
}
// RegisterOcrBackend registers a OcrBackend implementation with the C runtime.
func RegisterOcrBackend(impl OcrBackend) error {
handle := cgo.NewHandle(impl)
// Build the C vtable DEBUG:c_vtable_struct=KREUZBERGKreuzbergOcrBackendVTable
vtable := C.KREUZBERGKreuzbergOcrBackendVTable{
process_image: (*[0]byte)(unsafe.Pointer(C.goOcrBackendProcessImage)),
process_image_file: (*[0]byte)(unsafe.Pointer(C.goOcrBackendProcessImageFile)),
supports_language: (*[0]byte)(unsafe.Pointer(C.goOcrBackendSupportsLanguage)),
backend_type: (*[0]byte)(unsafe.Pointer(C.goOcrBackendBackendType)),
supported_languages: (*[0]byte)(unsafe.Pointer(C.goOcrBackendSupportedLanguages)),
supports_table_detection: (*[0]byte)(unsafe.Pointer(C.goOcrBackendSupportsTableDetection)),
supports_document_processing: (*[0]byte)(unsafe.Pointer(C.goOcrBackendSupportsDocumentProcessing)),
process_document: (*[0]byte)(unsafe.Pointer(C.goOcrBackendProcessDocument)),
name_fn: (*[0]byte)(unsafe.Pointer(C.goOcrBackendName)),
version_fn: (*[0]byte)(unsafe.Pointer(C.goOcrBackendVersion)),
initialize_fn: (*[0]byte)(unsafe.Pointer(C.goOcrBackendInitialize)),
shutdown_fn: (*[0]byte)(unsafe.Pointer(C.goOcrBackendShutdown)),
free_string: (*[0]byte)(unsafe.Pointer(C.goOcrBackendFreeString)),
free_user_data: (*[0]byte)(unsafe.Pointer(C.goOcrBackendFreeUserData)),
}
// Call C registration
cName := C.CString(impl.Name())
defer C.free(unsafe.Pointer(cName))
var cErr *C.char
rc := C.kreuzberg_register_ocr_backend(
cName,
vtable,
unsafe.Pointer(uintptr(handle)),
&cErr,
)
if rc != 0 {
msg := "failed to register OcrBackend"
if cErr != nil {
msg = C.GoString(cErr)
C.kreuzberg_free_string(cErr)
}
handle.Delete()
return fmt.Errorf("%s", msg)
}
// Store handle by name for later cleanup on unregister
ocr_backendRegistry.store(impl.Name(), handle)
return nil
}
// UnregisterOcrBackend unregisters a OcrBackend implementation.
func UnregisterOcrBackend(name string) error {
cName := C.CString(name)
defer C.free(unsafe.Pointer(cName))
var cErr *C.char
rc := C.kreuzberg_unregister_ocr_backend(cName, &cErr)
if rc != 0 {
msg := "failed to unregister OcrBackend"
if cErr != nil {
msg = C.GoString(cErr)
C.kreuzberg_free_string(cErr)
}
return fmt.Errorf("%s", msg)
}
// Delete the handle now that Rust has unregistered the plugin
ocr_backendRegistry.delete(name)
return nil
}
// ClearOcrBackends removes all registered OcrBackend implementations.
func ClearOcrBackends() error {
var cErr *C.char
rc := C.kreuzberg_clear_ocr_backend(&cErr)
if rc != 0 {
msg := "failed to clear OcrBackend plugins"
if cErr != nil {
msg = C.GoString(cErr)
C.free(unsafe.Pointer(cErr))
}
return fmt.Errorf("%s", msg)
}
// Delete all handles now that Rust has cleared all plugins
ocr_backendRegistry.clear()
return nil
}
// PostProcessor defines the Go interface for the PostProcessor trait.
type PostProcessor interface {
// Name returns the plugin name.
Name() string
// Version returns the plugin version.
Version() string
// Initialize is called when the plugin is loaded.
Initialize() error
// Shutdown is called when the plugin is unloaded.
Shutdown() error
// process
Process(result ExtractionResult, config ExtractionConfig) error
// processing_stage
ProcessingStage() ProcessingStage
// should_process
ShouldProcess(_result ExtractionResult, _config ExtractionConfig) bool
// estimated_duration_ms
EstimatedDurationMs(_result ExtractionResult) uint64
// priority
Priority() int32
}
//export goPostProcessorProcess
func goPostProcessorProcess(
userData unsafe.Pointer,
result *C.char,
config *C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(PostProcessor)
if !ok {
return 1 // error: invalid handle
}
var goResult ExtractionResult
if result != nil {
json.Unmarshal([]byte(C.GoString(result)), &goResult)
}
var goConfig ExtractionConfig
if config != nil {
json.Unmarshal([]byte(C.GoString(config)), &goConfig)
}
// Call the method
err := impl.Process(goResult, goConfig)
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
return 0 // success
}
//export goPostProcessorProcessingStage
func goPostProcessorProcessingStage(
userData unsafe.Pointer,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(PostProcessor)
if !ok {
return 1 // error: invalid handle
}
// Call the method
result := impl.ProcessingStage()
jsonBytes, _ := json.Marshal(result)
cResult := C.CString(string(jsonBytes))
*outResult = cResult
return 0 // success
}
//export goPostProcessorShouldProcess
func goPostProcessorShouldProcess(
userData unsafe.Pointer,
_result *C.char,
_config *C.char,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(PostProcessor)
if !ok {
return 1 // error: invalid handle
}
var go_result ExtractionResult
if _result != nil {
json.Unmarshal([]byte(C.GoString(_result)), &go_result)
}
var go_config ExtractionConfig
if _config != nil {
json.Unmarshal([]byte(C.GoString(_config)), &go_config)
}
// Call the method
result := impl.ShouldProcess(go_result, go_config)
jsonBytes, _ := json.Marshal(result)
cResult := C.CString(string(jsonBytes))
*outResult = cResult
return 0 // success
}
//export goPostProcessorEstimatedDurationMs
func goPostProcessorEstimatedDurationMs(
userData unsafe.Pointer,
_result *C.char,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(PostProcessor)
if !ok {
return 1 // error: invalid handle
}
var go_result ExtractionResult
if _result != nil {
json.Unmarshal([]byte(C.GoString(_result)), &go_result)
}
// Call the method
result := impl.EstimatedDurationMs(go_result)
jsonBytes, _ := json.Marshal(result)
cResult := C.CString(string(jsonBytes))
*outResult = cResult
return 0 // success
}
//export goPostProcessorPriority
func goPostProcessorPriority(
userData unsafe.Pointer,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(PostProcessor)
if !ok {
return 1 // error: invalid handle
}
// Call the method
result := impl.Priority()
jsonBytes, _ := json.Marshal(result)
cResult := C.CString(string(jsonBytes))
*outResult = cResult
return 0 // success
}
//export goPostProcessorName
func goPostProcessorName(userData unsafe.Pointer, outResult **C.char, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(PostProcessor)
if !ok {
return 1
}
name := impl.Name()
cName := C.CString(name)
*outResult = cName
return 0
}
//export goPostProcessorVersion
func goPostProcessorVersion(userData unsafe.Pointer, outResult **C.char, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(PostProcessor)
if !ok {
return 1
}
version := impl.Version()
cVersion := C.CString(version)
*outResult = cVersion
return 0
}
//export goPostProcessorInitialize
func goPostProcessorInitialize(userData unsafe.Pointer, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(PostProcessor)
if !ok {
return 1
}
err := impl.Initialize()
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
return 0
}
//export goPostProcessorShutdown
func goPostProcessorShutdown(userData unsafe.Pointer, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(PostProcessor)
if !ok {
return 1
}
err := impl.Shutdown()
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
return 0
}
//export goPostProcessorFreeUserData
func goPostProcessorFreeUserData(userData unsafe.Pointer) {
// No-op to avoid cleanup-queue panics. Handles cleaned in Unregister().
}
//export goPostProcessorFreeString
func goPostProcessorFreeString(ptr *C.char) {
if ptr != nil {
C.free(unsafe.Pointer(ptr))
}
}
// RegisterPostProcessor registers a PostProcessor implementation with the C runtime.
func RegisterPostProcessor(impl PostProcessor) error {
handle := cgo.NewHandle(impl)
// Build the C vtable DEBUG:c_vtable_struct=KREUZBERGKreuzbergPostProcessorVTable
vtable := C.KREUZBERGKreuzbergPostProcessorVTable{
process: (*[0]byte)(unsafe.Pointer(C.goPostProcessorProcess)),
processing_stage: (*[0]byte)(unsafe.Pointer(C.goPostProcessorProcessingStage)),
should_process: (*[0]byte)(unsafe.Pointer(C.goPostProcessorShouldProcess)),
estimated_duration_ms: (*[0]byte)(unsafe.Pointer(C.goPostProcessorEstimatedDurationMs)),
priority: (*[0]byte)(unsafe.Pointer(C.goPostProcessorPriority)),
name_fn: (*[0]byte)(unsafe.Pointer(C.goPostProcessorName)),
version_fn: (*[0]byte)(unsafe.Pointer(C.goPostProcessorVersion)),
initialize_fn: (*[0]byte)(unsafe.Pointer(C.goPostProcessorInitialize)),
shutdown_fn: (*[0]byte)(unsafe.Pointer(C.goPostProcessorShutdown)),
free_string: (*[0]byte)(unsafe.Pointer(C.goPostProcessorFreeString)),
free_user_data: (*[0]byte)(unsafe.Pointer(C.goPostProcessorFreeUserData)),
}
// Call C registration
cName := C.CString(impl.Name())
defer C.free(unsafe.Pointer(cName))
var cErr *C.char
rc := C.kreuzberg_register_post_processor(
cName,
vtable,
unsafe.Pointer(uintptr(handle)),
&cErr,
)
if rc != 0 {
msg := "failed to register PostProcessor"
if cErr != nil {
msg = C.GoString(cErr)
C.kreuzberg_free_string(cErr)
}
handle.Delete()
return fmt.Errorf("%s", msg)
}
// Store handle by name for later cleanup on unregister
post_processorRegistry.store(impl.Name(), handle)
return nil
}
// UnregisterPostProcessor unregisters a PostProcessor implementation.
func UnregisterPostProcessor(name string) error {
cName := C.CString(name)
defer C.free(unsafe.Pointer(cName))
var cErr *C.char
rc := C.kreuzberg_unregister_post_processor(cName, &cErr)
if rc != 0 {
msg := "failed to unregister PostProcessor"
if cErr != nil {
msg = C.GoString(cErr)
C.kreuzberg_free_string(cErr)
}
return fmt.Errorf("%s", msg)
}
// Delete the handle now that Rust has unregistered the plugin
post_processorRegistry.delete(name)
return nil
}
// ClearPostProcessors removes all registered PostProcessor implementations.
func ClearPostProcessors() error {
var cErr *C.char
rc := C.kreuzberg_clear_post_processor(&cErr)
if rc != 0 {
msg := "failed to clear PostProcessor plugins"
if cErr != nil {
msg = C.GoString(cErr)
C.free(unsafe.Pointer(cErr))
}
return fmt.Errorf("%s", msg)
}
// Delete all handles now that Rust has cleared all plugins
post_processorRegistry.clear()
return nil
}
// Validator defines the Go interface for the Validator trait.
type Validator interface {
// Name returns the plugin name.
Name() string
// Version returns the plugin version.
Version() string
// Initialize is called when the plugin is loaded.
Initialize() error
// Shutdown is called when the plugin is unloaded.
Shutdown() error
// validate
Validate(result ExtractionResult, config ExtractionConfig) error
// should_validate
ShouldValidate(_result ExtractionResult, _config ExtractionConfig) bool
// priority
Priority() int32
}
//export goValidatorValidate
func goValidatorValidate(
userData unsafe.Pointer,
result *C.char,
config *C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(Validator)
if !ok {
return 1 // error: invalid handle
}
var goResult ExtractionResult
if result != nil {
json.Unmarshal([]byte(C.GoString(result)), &goResult)
}
var goConfig ExtractionConfig
if config != nil {
json.Unmarshal([]byte(C.GoString(config)), &goConfig)
}
// Call the method
err := impl.Validate(goResult, goConfig)
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
return 0 // success
}
//export goValidatorShouldValidate
func goValidatorShouldValidate(
userData unsafe.Pointer,
_result *C.char,
_config *C.char,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(Validator)
if !ok {
return 1 // error: invalid handle
}
var go_result ExtractionResult
if _result != nil {
json.Unmarshal([]byte(C.GoString(_result)), &go_result)
}
var go_config ExtractionConfig
if _config != nil {
json.Unmarshal([]byte(C.GoString(_config)), &go_config)
}
// Call the method
result := impl.ShouldValidate(go_result, go_config)
jsonBytes, _ := json.Marshal(result)
cResult := C.CString(string(jsonBytes))
*outResult = cResult
return 0 // success
}
//export goValidatorPriority
func goValidatorPriority(
userData unsafe.Pointer,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(Validator)
if !ok {
return 1 // error: invalid handle
}
// Call the method
result := impl.Priority()
jsonBytes, _ := json.Marshal(result)
cResult := C.CString(string(jsonBytes))
*outResult = cResult
return 0 // success
}
//export goValidatorName
func goValidatorName(userData unsafe.Pointer, outResult **C.char, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(Validator)
if !ok {
return 1
}
name := impl.Name()
cName := C.CString(name)
*outResult = cName
return 0
}
//export goValidatorVersion
func goValidatorVersion(userData unsafe.Pointer, outResult **C.char, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(Validator)
if !ok {
return 1
}
version := impl.Version()
cVersion := C.CString(version)
*outResult = cVersion
return 0
}
//export goValidatorInitialize
func goValidatorInitialize(userData unsafe.Pointer, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(Validator)
if !ok {
return 1
}
err := impl.Initialize()
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
return 0
}
//export goValidatorShutdown
func goValidatorShutdown(userData unsafe.Pointer, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(Validator)
if !ok {
return 1
}
err := impl.Shutdown()
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
return 0
}
//export goValidatorFreeUserData
func goValidatorFreeUserData(userData unsafe.Pointer) {
// No-op to avoid cleanup-queue panics. Handles cleaned in Unregister().
}
//export goValidatorFreeString
func goValidatorFreeString(ptr *C.char) {
if ptr != nil {
C.free(unsafe.Pointer(ptr))
}
}
// RegisterValidator registers a Validator implementation with the C runtime.
func RegisterValidator(impl Validator) error {
handle := cgo.NewHandle(impl)
// Build the C vtable DEBUG:c_vtable_struct=KREUZBERGKreuzbergValidatorVTable
vtable := C.KREUZBERGKreuzbergValidatorVTable{
validate: (*[0]byte)(unsafe.Pointer(C.goValidatorValidate)),
should_validate: (*[0]byte)(unsafe.Pointer(C.goValidatorShouldValidate)),
priority: (*[0]byte)(unsafe.Pointer(C.goValidatorPriority)),
name_fn: (*[0]byte)(unsafe.Pointer(C.goValidatorName)),
version_fn: (*[0]byte)(unsafe.Pointer(C.goValidatorVersion)),
initialize_fn: (*[0]byte)(unsafe.Pointer(C.goValidatorInitialize)),
shutdown_fn: (*[0]byte)(unsafe.Pointer(C.goValidatorShutdown)),
free_string: (*[0]byte)(unsafe.Pointer(C.goValidatorFreeString)),
free_user_data: (*[0]byte)(unsafe.Pointer(C.goValidatorFreeUserData)),
}
// Call C registration
cName := C.CString(impl.Name())
defer C.free(unsafe.Pointer(cName))
var cErr *C.char
rc := C.kreuzberg_register_validator(
cName,
vtable,
unsafe.Pointer(uintptr(handle)),
&cErr,
)
if rc != 0 {
msg := "failed to register Validator"
if cErr != nil {
msg = C.GoString(cErr)
C.kreuzberg_free_string(cErr)
}
handle.Delete()
return fmt.Errorf("%s", msg)
}
// Store handle by name for later cleanup on unregister
validatorRegistry.store(impl.Name(), handle)
return nil
}
// UnregisterValidator unregisters a Validator implementation.
func UnregisterValidator(name string) error {
cName := C.CString(name)
defer C.free(unsafe.Pointer(cName))
var cErr *C.char
rc := C.kreuzberg_unregister_validator(cName, &cErr)
if rc != 0 {
msg := "failed to unregister Validator"
if cErr != nil {
msg = C.GoString(cErr)
C.kreuzberg_free_string(cErr)
}
return fmt.Errorf("%s", msg)
}
// Delete the handle now that Rust has unregistered the plugin
validatorRegistry.delete(name)
return nil
}
// ClearValidators removes all registered Validator implementations.
func ClearValidators() error {
var cErr *C.char
rc := C.kreuzberg_clear_validator(&cErr)
if rc != 0 {
msg := "failed to clear Validator plugins"
if cErr != nil {
msg = C.GoString(cErr)
C.free(unsafe.Pointer(cErr))
}
return fmt.Errorf("%s", msg)
}
// Delete all handles now that Rust has cleared all plugins
validatorRegistry.clear()
return nil
}
// EmbeddingBackend defines the Go interface for the EmbeddingBackend trait.
type EmbeddingBackend interface {
// Name returns the plugin name.
Name() string
// Version returns the plugin version.
Version() string
// Initialize is called when the plugin is loaded.
Initialize() error
// Shutdown is called when the plugin is unloaded.
Shutdown() error
// dimensions
Dimensions() uint
// embed
Embed(texts []string) ([][]float32, error)
}
//export goEmbeddingBackendDimensions
func goEmbeddingBackendDimensions(
userData unsafe.Pointer,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(EmbeddingBackend)
if !ok {
return 1 // error: invalid handle
}
// Call the method
result := impl.Dimensions()
jsonBytes, _ := json.Marshal(result)
cResult := C.CString(string(jsonBytes))
*outResult = cResult
return 0 // success
}
//export goEmbeddingBackendEmbed
func goEmbeddingBackendEmbed(
userData unsafe.Pointer,
texts *C.char,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(EmbeddingBackend)
if !ok {
return 1 // error: invalid handle
}
var goTexts []string
if texts != nil {
json.Unmarshal([]byte(C.GoString(texts)), &goTexts)
}
// Call the method
result, err := impl.Embed(goTexts)
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
jsonBytes, _ := json.Marshal(result)
cResult := C.CString(string(jsonBytes))
*outResult = cResult
return 0 // success
}
//export goEmbeddingBackendName
func goEmbeddingBackendName(userData unsafe.Pointer, outResult **C.char, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(EmbeddingBackend)
if !ok {
return 1
}
name := impl.Name()
cName := C.CString(name)
*outResult = cName
return 0
}
//export goEmbeddingBackendVersion
func goEmbeddingBackendVersion(userData unsafe.Pointer, outResult **C.char, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(EmbeddingBackend)
if !ok {
return 1
}
version := impl.Version()
cVersion := C.CString(version)
*outResult = cVersion
return 0
}
//export goEmbeddingBackendInitialize
func goEmbeddingBackendInitialize(userData unsafe.Pointer, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(EmbeddingBackend)
if !ok {
return 1
}
err := impl.Initialize()
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
return 0
}
//export goEmbeddingBackendShutdown
func goEmbeddingBackendShutdown(userData unsafe.Pointer, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(EmbeddingBackend)
if !ok {
return 1
}
err := impl.Shutdown()
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
return 0
}
//export goEmbeddingBackendFreeUserData
func goEmbeddingBackendFreeUserData(userData unsafe.Pointer) {
// No-op to avoid cleanup-queue panics. Handles cleaned in Unregister().
}
//export goEmbeddingBackendFreeString
func goEmbeddingBackendFreeString(ptr *C.char) {
if ptr != nil {
C.free(unsafe.Pointer(ptr))
}
}
// RegisterEmbeddingBackend registers a EmbeddingBackend implementation with the C runtime.
func RegisterEmbeddingBackend(impl EmbeddingBackend) error {
handle := cgo.NewHandle(impl)
// Build the C vtable DEBUG:c_vtable_struct=KREUZBERGKreuzbergEmbeddingBackendVTable
vtable := C.KREUZBERGKreuzbergEmbeddingBackendVTable{
dimensions: (*[0]byte)(unsafe.Pointer(C.goEmbeddingBackendDimensions)),
embed: (*[0]byte)(unsafe.Pointer(C.goEmbeddingBackendEmbed)),
name_fn: (*[0]byte)(unsafe.Pointer(C.goEmbeddingBackendName)),
version_fn: (*[0]byte)(unsafe.Pointer(C.goEmbeddingBackendVersion)),
initialize_fn: (*[0]byte)(unsafe.Pointer(C.goEmbeddingBackendInitialize)),
shutdown_fn: (*[0]byte)(unsafe.Pointer(C.goEmbeddingBackendShutdown)),
free_string: (*[0]byte)(unsafe.Pointer(C.goEmbeddingBackendFreeString)),
free_user_data: (*[0]byte)(unsafe.Pointer(C.goEmbeddingBackendFreeUserData)),
}
// Call C registration
cName := C.CString(impl.Name())
defer C.free(unsafe.Pointer(cName))
var cErr *C.char
rc := C.kreuzberg_register_embedding_backend(
cName,
vtable,
unsafe.Pointer(uintptr(handle)),
&cErr,
)
if rc != 0 {
msg := "failed to register EmbeddingBackend"
if cErr != nil {
msg = C.GoString(cErr)
C.kreuzberg_free_string(cErr)
}
handle.Delete()
return fmt.Errorf("%s", msg)
}
// Store handle by name for later cleanup on unregister
embedding_backendRegistry.store(impl.Name(), handle)
return nil
}
// UnregisterEmbeddingBackend unregisters a EmbeddingBackend implementation.
func UnregisterEmbeddingBackend(name string) error {
cName := C.CString(name)
defer C.free(unsafe.Pointer(cName))
var cErr *C.char
rc := C.kreuzberg_unregister_embedding_backend(cName, &cErr)
if rc != 0 {
msg := "failed to unregister EmbeddingBackend"
if cErr != nil {
msg = C.GoString(cErr)
C.kreuzberg_free_string(cErr)
}
return fmt.Errorf("%s", msg)
}
// Delete the handle now that Rust has unregistered the plugin
embedding_backendRegistry.delete(name)
return nil
}
// ClearEmbeddingBackends removes all registered EmbeddingBackend implementations.
func ClearEmbeddingBackends() error {
var cErr *C.char
rc := C.kreuzberg_clear_embedding_backend(&cErr)
if rc != 0 {
msg := "failed to clear EmbeddingBackend plugins"
if cErr != nil {
msg = C.GoString(cErr)
C.free(unsafe.Pointer(cErr))
}
return fmt.Errorf("%s", msg)
}
// Delete all handles now that Rust has cleared all plugins
embedding_backendRegistry.clear()
return nil
}
// DocumentExtractor defines the Go interface for the DocumentExtractor trait.
type DocumentExtractor interface {
// Name returns the plugin name.
Name() string
// Version returns the plugin version.
Version() string
// Initialize is called when the plugin is loaded.
Initialize() error
// Shutdown is called when the plugin is unloaded.
Shutdown() error
// extract_bytes
ExtractBytes(content []byte, mime_type string, config ExtractionConfig) (json.RawMessage, error)
// extract_file
ExtractFile(path string, mime_type string, config ExtractionConfig) (json.RawMessage, error)
// supported_mime_types
SupportedMimeTypes() []string
// priority
Priority() int32
// can_handle
CanHandle(_path string, _mime_type string) bool
}
//export goDocumentExtractorExtractBytes
func goDocumentExtractorExtractBytes(
userData unsafe.Pointer,
content *C.uint8_t,
contentLen C.size_t,
mime_type *C.char,
config *C.char,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(DocumentExtractor)
if !ok {
return 1 // error: invalid handle
}
var goContent []byte
if content != nil {
goContent = unsafe.Slice((*byte)(unsafe.Pointer(content)), int(contentLen))
}
goMime_type := C.GoString(mime_type)
var goConfig ExtractionConfig
if config != nil {
json.Unmarshal([]byte(C.GoString(config)), &goConfig)
}
// Call the method
result, err := impl.ExtractBytes(goContent, goMime_type, goConfig)
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
cResult := C.CString(string(result))
*outResult = cResult
return 0 // success
}
//export goDocumentExtractorExtractFile
func goDocumentExtractorExtractFile(
userData unsafe.Pointer,
path *C.char,
mime_type *C.char,
config *C.char,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(DocumentExtractor)
if !ok {
return 1 // error: invalid handle
}
goPath := C.GoString(path)
goMime_type := C.GoString(mime_type)
var goConfig ExtractionConfig
if config != nil {
json.Unmarshal([]byte(C.GoString(config)), &goConfig)
}
// Call the method
result, err := impl.ExtractFile(goPath, goMime_type, goConfig)
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
cResult := C.CString(string(result))
*outResult = cResult
return 0 // success
}
//export goDocumentExtractorSupportedMimeTypes
func goDocumentExtractorSupportedMimeTypes(
userData unsafe.Pointer,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(DocumentExtractor)
if !ok {
return 1 // error: invalid handle
}
// Call the method
result := impl.SupportedMimeTypes()
jsonBytes, _ := json.Marshal(result)
cResult := C.CString(string(jsonBytes))
*outResult = cResult
return 0 // success
}
//export goDocumentExtractorPriority
func goDocumentExtractorPriority(
userData unsafe.Pointer,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(DocumentExtractor)
if !ok {
return 1 // error: invalid handle
}
// Call the method
result := impl.Priority()
jsonBytes, _ := json.Marshal(result)
cResult := C.CString(string(jsonBytes))
*outResult = cResult
return 0 // success
}
//export goDocumentExtractorCanHandle
func goDocumentExtractorCanHandle(
userData unsafe.Pointer,
_path *C.char,
_mime_type *C.char,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(DocumentExtractor)
if !ok {
return 1 // error: invalid handle
}
go_path := C.GoString(_path)
go_mime_type := C.GoString(_mime_type)
// Call the method
result := impl.CanHandle(go_path, go_mime_type)
jsonBytes, _ := json.Marshal(result)
cResult := C.CString(string(jsonBytes))
*outResult = cResult
return 0 // success
}
//export goDocumentExtractorName
func goDocumentExtractorName(userData unsafe.Pointer, outResult **C.char, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(DocumentExtractor)
if !ok {
return 1
}
name := impl.Name()
cName := C.CString(name)
*outResult = cName
return 0
}
//export goDocumentExtractorVersion
func goDocumentExtractorVersion(userData unsafe.Pointer, outResult **C.char, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(DocumentExtractor)
if !ok {
return 1
}
version := impl.Version()
cVersion := C.CString(version)
*outResult = cVersion
return 0
}
//export goDocumentExtractorInitialize
func goDocumentExtractorInitialize(userData unsafe.Pointer, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(DocumentExtractor)
if !ok {
return 1
}
err := impl.Initialize()
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
return 0
}
//export goDocumentExtractorShutdown
func goDocumentExtractorShutdown(userData unsafe.Pointer, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(DocumentExtractor)
if !ok {
return 1
}
err := impl.Shutdown()
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
return 0
}
//export goDocumentExtractorFreeUserData
func goDocumentExtractorFreeUserData(userData unsafe.Pointer) {
// No-op to avoid cleanup-queue panics. Handles cleaned in Unregister().
}
//export goDocumentExtractorFreeString
func goDocumentExtractorFreeString(ptr *C.char) {
if ptr != nil {
C.free(unsafe.Pointer(ptr))
}
}
// RegisterDocumentExtractor registers a DocumentExtractor implementation with the C runtime.
func RegisterDocumentExtractor(impl DocumentExtractor) error {
handle := cgo.NewHandle(impl)
// Build the C vtable DEBUG:c_vtable_struct=KREUZBERGKreuzbergDocumentExtractorVTable
vtable := C.KREUZBERGKreuzbergDocumentExtractorVTable{
extract_bytes: (*[0]byte)(unsafe.Pointer(C.goDocumentExtractorExtractBytes)),
extract_file: (*[0]byte)(unsafe.Pointer(C.goDocumentExtractorExtractFile)),
supported_mime_types: (*[0]byte)(unsafe.Pointer(C.goDocumentExtractorSupportedMimeTypes)),
priority: (*[0]byte)(unsafe.Pointer(C.goDocumentExtractorPriority)),
can_handle: (*[0]byte)(unsafe.Pointer(C.goDocumentExtractorCanHandle)),
name_fn: (*[0]byte)(unsafe.Pointer(C.goDocumentExtractorName)),
version_fn: (*[0]byte)(unsafe.Pointer(C.goDocumentExtractorVersion)),
initialize_fn: (*[0]byte)(unsafe.Pointer(C.goDocumentExtractorInitialize)),
shutdown_fn: (*[0]byte)(unsafe.Pointer(C.goDocumentExtractorShutdown)),
free_string: (*[0]byte)(unsafe.Pointer(C.goDocumentExtractorFreeString)),
free_user_data: (*[0]byte)(unsafe.Pointer(C.goDocumentExtractorFreeUserData)),
}
// Call C registration
cName := C.CString(impl.Name())
defer C.free(unsafe.Pointer(cName))
var cErr *C.char
rc := C.kreuzberg_register_document_extractor(
cName,
vtable,
unsafe.Pointer(uintptr(handle)),
&cErr,
)
if rc != 0 {
msg := "failed to register DocumentExtractor"
if cErr != nil {
msg = C.GoString(cErr)
C.kreuzberg_free_string(cErr)
}
handle.Delete()
return fmt.Errorf("%s", msg)
}
// Store handle by name for later cleanup on unregister
document_extractorRegistry.store(impl.Name(), handle)
return nil
}
// UnregisterDocumentExtractor unregisters a DocumentExtractor implementation.
func UnregisterDocumentExtractor(name string) error {
cName := C.CString(name)
defer C.free(unsafe.Pointer(cName))
var cErr *C.char
rc := C.kreuzberg_unregister_document_extractor(cName, &cErr)
if rc != 0 {
msg := "failed to unregister DocumentExtractor"
if cErr != nil {
msg = C.GoString(cErr)
C.kreuzberg_free_string(cErr)
}
return fmt.Errorf("%s", msg)
}
// Delete the handle now that Rust has unregistered the plugin
document_extractorRegistry.delete(name)
return nil
}
// ClearDocumentExtractors removes all registered DocumentExtractor implementations.
func ClearDocumentExtractors() error {
var cErr *C.char
rc := C.kreuzberg_clear_document_extractor(&cErr)
if rc != 0 {
msg := "failed to clear DocumentExtractor plugins"
if cErr != nil {
msg = C.GoString(cErr)
C.free(unsafe.Pointer(cErr))
}
return fmt.Errorf("%s", msg)
}
// Delete all handles now that Rust has cleared all plugins
document_extractorRegistry.clear()
return nil
}
// Renderer defines the Go interface for the Renderer trait.
type Renderer interface {
// Name returns the plugin name.
Name() string
// Version returns the plugin version.
Version() string
// Initialize is called when the plugin is loaded.
Initialize() error
// Shutdown is called when the plugin is unloaded.
Shutdown() error
// render
Render(doc json.RawMessage) (string, error)
}
//export goRendererRender
func goRendererRender(
userData unsafe.Pointer,
doc *C.char,
outResult **C.char,
outError **C.char,
) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(Renderer)
if !ok {
return 1 // error: invalid handle
}
var goDoc json.RawMessage
if doc != nil {
goDoc = json.RawMessage(C.GoString(doc))
}
// Call the method
result, err := impl.Render(goDoc)
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
cResult := C.CString(result)
*outResult = cResult
return 0 // success
}
//export goRendererName
func goRendererName(userData unsafe.Pointer, outResult **C.char, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(Renderer)
if !ok {
return 1
}
name := impl.Name()
cName := C.CString(name)
*outResult = cName
return 0
}
//export goRendererVersion
func goRendererVersion(userData unsafe.Pointer, outResult **C.char, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(Renderer)
if !ok {
return 1
}
version := impl.Version()
cVersion := C.CString(version)
*outResult = cVersion
return 0
}
//export goRendererInitialize
func goRendererInitialize(userData unsafe.Pointer, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(Renderer)
if !ok {
return 1
}
err := impl.Initialize()
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
return 0
}
//export goRendererShutdown
func goRendererShutdown(userData unsafe.Pointer, outError **C.char) C.int32_t {
handle := cgo.Handle(uintptr(unsafe.Pointer(userData)))
impl, ok := handle.Value().(Renderer)
if !ok {
return 1
}
err := impl.Shutdown()
if err != nil {
cErr := C.CString(err.Error())
*outError = cErr
return 1
}
return 0
}
//export goRendererFreeUserData
func goRendererFreeUserData(userData unsafe.Pointer) {
// No-op to avoid cleanup-queue panics. Handles cleaned in Unregister().
}
//export goRendererFreeString
func goRendererFreeString(ptr *C.char) {
if ptr != nil {
C.free(unsafe.Pointer(ptr))
}
}
// RegisterRenderer registers a Renderer implementation with the C runtime.
func RegisterRenderer(impl Renderer) error {
handle := cgo.NewHandle(impl)
// Build the C vtable DEBUG:c_vtable_struct=KREUZBERGKreuzbergRendererVTable
vtable := C.KREUZBERGKreuzbergRendererVTable{
render: (*[0]byte)(unsafe.Pointer(C.goRendererRender)),
name_fn: (*[0]byte)(unsafe.Pointer(C.goRendererName)),
version_fn: (*[0]byte)(unsafe.Pointer(C.goRendererVersion)),
initialize_fn: (*[0]byte)(unsafe.Pointer(C.goRendererInitialize)),
shutdown_fn: (*[0]byte)(unsafe.Pointer(C.goRendererShutdown)),
free_string: (*[0]byte)(unsafe.Pointer(C.goRendererFreeString)),
free_user_data: (*[0]byte)(unsafe.Pointer(C.goRendererFreeUserData)),
}
// Call C registration
cName := C.CString(impl.Name())
defer C.free(unsafe.Pointer(cName))
var cErr *C.char
rc := C.kreuzberg_register_renderer(
cName,
vtable,
unsafe.Pointer(uintptr(handle)),
&cErr,
)
if rc != 0 {
msg := "failed to register Renderer"
if cErr != nil {
msg = C.GoString(cErr)
C.kreuzberg_free_string(cErr)
}
handle.Delete()
return fmt.Errorf("%s", msg)
}
// Store handle by name for later cleanup on unregister
rendererRegistry.store(impl.Name(), handle)
return nil
}
// UnregisterRenderer unregisters a Renderer implementation.
func UnregisterRenderer(name string) error {
cName := C.CString(name)
defer C.free(unsafe.Pointer(cName))
var cErr *C.char
rc := C.kreuzberg_unregister_renderer(cName, &cErr)
if rc != 0 {
msg := "failed to unregister Renderer"
if cErr != nil {
msg = C.GoString(cErr)
C.kreuzberg_free_string(cErr)
}
return fmt.Errorf("%s", msg)
}
// Delete the handle now that Rust has unregistered the plugin
rendererRegistry.delete(name)
return nil
}
// ClearRenderers removes all registered Renderer implementations.
func ClearRenderers() error {
var cErr *C.char
rc := C.kreuzberg_clear_renderer(&cErr)
if rc != 0 {
msg := "failed to clear Renderer plugins"
if cErr != nil {
msg = C.GoString(cErr)
C.free(unsafe.Pointer(cErr))
}
return fmt.Errorf("%s", msg)
}
// Delete all handles now that Rust has cleared all plugins
rendererRegistry.clear()
return nil
}