Skip to content

Commit 913a48a

Browse files
committed
chore: M5 CI/Workflow Sweep - final synchronisation
1 parent 29d056f commit 913a48a

2 files changed

Lines changed: 212 additions & 34 deletions

File tree

ffi/zig/src/main.zig

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// {{PROJECT}} FFI Implementation
1+
// UNIVERSAL_CHAT_EXTRACTOR FFI Implementation
22
//
33
// This module implements the C-compatible FFI declared in src/abi/Foreign.idr
44
// All types and layouts must match the Idris2 ABI definitions.
@@ -9,7 +9,7 @@ const std = @import("std");
99

1010
// Version information (keep in sync with project)
1111
const VERSION = "0.1.0";
12-
const BUILD_INFO = "{{PROJECT}} built with Zig " ++ @import("builtin").zig_version_string;
12+
const BUILD_INFO = "UNIVERSAL_CHAT_EXTRACTOR built with Zig " ++ @import("builtin").zig_version_string;
1313

1414
/// Thread-local error storage
1515
threadlocal var last_error: ?[]const u8 = null;
@@ -51,7 +51,7 @@ pub const Handle = opaque {
5151

5252
/// Initialize the library
5353
/// Returns a handle, or null on failure
54-
export fn {{project}}_init() ?*Handle {
54+
export fn universal_chat_extractor_init() ?*Handle {
5555
const allocator = std.heap.c_allocator;
5656

5757
const handle = allocator.create(Handle) catch {
@@ -70,7 +70,7 @@ export fn {{project}}_init() ?*Handle {
7070
}
7171

7272
/// Free the library handle
73-
export fn {{project}}_free(handle: ?*Handle) void {
73+
export fn universal_chat_extractor_free(handle: ?*Handle) void {
7474
const h = handle orelse return;
7575
const allocator = h.allocator;
7676

@@ -86,7 +86,7 @@ export fn {{project}}_free(handle: ?*Handle) void {
8686
//==============================================================================
8787

8888
/// Process data (example operation)
89-
export fn {{project}}_process(handle: ?*Handle, input: u32) Result {
89+
export fn universal_chat_extractor_process(handle: ?*Handle, input: u32) Result {
9090
const h = handle orelse {
9191
setError("Null handle");
9292
return .null_pointer;
@@ -110,7 +110,7 @@ export fn {{project}}_process(handle: ?*Handle, input: u32) Result {
110110

111111
/// Get a string result (example)
112112
/// Caller must free the returned string
113-
export fn {{project}}_get_string(handle: ?*Handle) ?[*:0]const u8 {
113+
export fn universal_chat_extractor_get_string(handle: ?*Handle) ?[*:0]const u8 {
114114
const h = handle orelse {
115115
setError("Null handle");
116116
return null;
@@ -132,7 +132,7 @@ export fn {{project}}_get_string(handle: ?*Handle) ?[*:0]const u8 {
132132
}
133133

134134
/// Free a string allocated by the library
135-
export fn {{project}}_free_string(str: ?[*:0]const u8) void {
135+
export fn universal_chat_extractor_free_string(str: ?[*:0]const u8) void {
136136
const s = str orelse return;
137137
const allocator = std.heap.c_allocator;
138138

@@ -145,7 +145,7 @@ export fn {{project}}_free_string(str: ?[*:0]const u8) void {
145145
//==============================================================================
146146

147147
/// Process an array of data
148-
export fn {{project}}_process_array(
148+
export fn universal_chat_extractor_process_array(
149149
handle: ?*Handle,
150150
buffer: ?[*]const u8,
151151
len: u32,
@@ -181,7 +181,7 @@ export fn {{project}}_process_array(
181181

182182
/// Get the last error message
183183
/// Returns null if no error
184-
export fn {{project}}_last_error() ?[*:0]const u8 {
184+
export fn universal_chat_extractor_last_error() ?[*:0]const u8 {
185185
const err = last_error orelse return null;
186186

187187
// Return C string (static storage, no need to free)
@@ -195,12 +195,12 @@ export fn {{project}}_last_error() ?[*:0]const u8 {
195195
//==============================================================================
196196

197197
/// Get the library version
198-
export fn {{project}}_version() [*:0]const u8 {
198+
export fn universal_chat_extractor_version() [*:0]const u8 {
199199
return VERSION.ptr;
200200
}
201201

202202
/// Get build information
203-
export fn {{project}}_build_info() [*:0]const u8 {
203+
export fn universal_chat_extractor_build_info() [*:0]const u8 {
204204
return BUILD_INFO.ptr;
205205
}
206206

@@ -212,7 +212,7 @@ export fn {{project}}_build_info() [*:0]const u8 {
212212
pub const Callback = *const fn (u64, u32) callconv(.C) u32;
213213

214214
/// Register a callback
215-
export fn {{project}}_register_callback(
215+
export fn universal_chat_extractor_register_callback(
216216
handle: ?*Handle,
217217
callback: ?Callback,
218218
) Result {
@@ -243,7 +243,7 @@ export fn {{project}}_register_callback(
243243
//==============================================================================
244244

245245
/// Check if handle is initialized
246-
export fn {{project}}_is_initialized(handle: ?*Handle) u32 {
246+
export fn universal_chat_extractor_is_initialized(handle: ?*Handle) u32 {
247247
const h = handle orelse return 0;
248248
return if (h.initialized) 1 else 0;
249249
}
@@ -253,22 +253,22 @@ export fn {{project}}_is_initialized(handle: ?*Handle) u32 {
253253
//==============================================================================
254254

255255
test "lifecycle" {
256-
const handle = {{project}}_init() orelse return error.InitFailed;
257-
defer {{project}}_free(handle);
256+
const handle = universal_chat_extractor_init() orelse return error.InitFailed;
257+
defer universal_chat_extractor_free(handle);
258258

259-
try std.testing.expect({{project}}_is_initialized(handle) == 1);
259+
try std.testing.expect(universal_chat_extractor_is_initialized(handle) == 1);
260260
}
261261

262262
test "error handling" {
263-
const result = {{project}}_process(null, 0);
263+
const result = universal_chat_extractor_process(null, 0);
264264
try std.testing.expectEqual(Result.null_pointer, result);
265265

266-
const err = {{project}}_last_error();
266+
const err = universal_chat_extractor_last_error();
267267
try std.testing.expect(err != null);
268268
}
269269

270270
test "version" {
271-
const ver = {{project}}_version();
271+
const ver = universal_chat_extractor_version();
272272
const ver_str = std.mem.span(ver);
273273
try std.testing.expectEqualStrings(VERSION, ver_str);
274274
}

src/abi/Foreign.idr

Lines changed: 193 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,217 @@
1-
-- SPDX-License-Identifier: PMPL-1.0-or-later
2-
||| UNIVERSAL-CHAT-EXTRACTOR — FFI Bridge Declarations
1+
||| SPDX-License-Identifier: PMPL-1.0-or-later
2+
||| Foreign Function Interface Declarations for UNIVERSAL_CHAT_EXTRACTOR
33
|||
4-
||| This module defines the formal bridge to the native chat-extraction
5-
||| kernel. It provides the low-level signatures required to process
6-
||| heterogeneous chat logs (Slack, Discord, Teams) via a unified API.
4+
||| This module declares all C-compatible functions that will be
5+
||| implemented in the Zig FFI layer.
6+
|||
7+
||| All functions are declared here with type signatures and safety proofs.
8+
||| Implementations live in ffi/zig/
79

8-
module UNIVERSAL_CHAT_EXTRACTOR.ABI.Foreign
10+
module UniversalChatExtractor.ABI.Foreign
911

10-
import UNIVERSAL_CHAT_EXTRACTOR.ABI.Types
11-
import UNIVERSAL_CHAT_EXTRACTOR.ABI.Layout
12+
import UniversalChatExtractor.ABI.Types
13+
import UniversalChatExtractor.ABI.Layout
1214

1315
%default total
1416

1517
--------------------------------------------------------------------------------
16-
-- Lifecycle
18+
-- Library Lifecycle
1719
--------------------------------------------------------------------------------
1820

19-
||| Initializes the extraction engine.
21+
||| Initialize the library
22+
||| Returns a handle to the library instance, or Nothing on failure
2023
export
21-
%foreign "C:chat_extractor_init, libextractor"
24+
%foreign "C:universal_chat_extractor_init, libuniversal_chat_extractor"
2225
prim__init : PrimIO Bits64
2326

24-
||| Safe initialization wrapper.
27+
||| Safe wrapper for library initialization
2528
export
2629
init : IO (Maybe Handle)
2730
init = do
2831
ptr <- primIO prim__init
2932
pure (createHandle ptr)
3033

31-
||| Shuts down the engine and releases native buffers.
34+
||| Clean up library resources
3235
export
33-
%foreign "C:chat_extractor_free, libextractor"
36+
%foreign "C:universal_chat_extractor_free, libuniversal_chat_extractor"
3437
prim__free : Bits64 -> PrimIO ()
3538

36-
||| Safe cleanup wrapper.
39+
||| Safe wrapper for cleanup
3740
export
3841
free : Handle -> IO ()
3942
free h = primIO (prim__free (handlePtr h))
43+
44+
--------------------------------------------------------------------------------
45+
-- Core Operations
46+
--------------------------------------------------------------------------------
47+
48+
||| Example operation: process data
49+
export
50+
%foreign "C:universal_chat_extractor_process, libuniversal_chat_extractor"
51+
prim__process : Bits64 -> Bits32 -> PrimIO Bits32
52+
53+
||| Safe wrapper with error handling
54+
export
55+
process : Handle -> Bits32 -> IO (Either Result Bits32)
56+
process h input = do
57+
result <- primIO (prim__process (handlePtr h) input)
58+
pure $ case result of
59+
0 => Left Error
60+
n => Right n
61+
62+
--------------------------------------------------------------------------------
63+
-- String Operations
64+
--------------------------------------------------------------------------------
65+
66+
||| Convert C string to Idris String
67+
export
68+
%foreign "support:idris2_getString, libidris2_support"
69+
prim__getString : Bits64 -> String
70+
71+
||| Free C string
72+
export
73+
%foreign "C:universal_chat_extractor_free_string, libuniversal_chat_extractor"
74+
prim__freeString : Bits64 -> PrimIO ()
75+
76+
||| Get string result from library
77+
export
78+
%foreign "C:universal_chat_extractor_get_string, libuniversal_chat_extractor"
79+
prim__getResult : Bits64 -> PrimIO Bits64
80+
81+
||| Safe string getter
82+
export
83+
getString : Handle -> IO (Maybe String)
84+
getString h = do
85+
ptr <- primIO (prim__getResult (handlePtr h))
86+
if ptr == 0
87+
then pure Nothing
88+
else do
89+
let str = prim__getString ptr
90+
primIO (prim__freeString ptr)
91+
pure (Just str)
92+
93+
--------------------------------------------------------------------------------
94+
-- Array/Buffer Operations
95+
--------------------------------------------------------------------------------
96+
97+
||| Process array data
98+
export
99+
%foreign "C:universal_chat_extractor_process_array, libuniversal_chat_extractor"
100+
prim__processArray : Bits64 -> Bits64 -> Bits32 -> PrimIO Bits32
101+
102+
||| Safe array processor
103+
export
104+
processArray : Handle -> (buffer : Bits64) -> (len : Bits32) -> IO (Either Result ())
105+
processArray h buf len = do
106+
result <- primIO (prim__processArray (handlePtr h) buf len)
107+
pure $ case resultFromInt result of
108+
Just Ok => Right ()
109+
Just err => Left err
110+
Nothing => Left Error
111+
where
112+
resultFromInt : Bits32 -> Maybe Result
113+
resultFromInt 0 = Just Ok
114+
resultFromInt 1 = Just Error
115+
resultFromInt 2 = Just InvalidParam
116+
resultFromInt 3 = Just OutOfMemory
117+
resultFromInt 4 = Just NullPointer
118+
resultFromInt _ = Nothing
119+
120+
--------------------------------------------------------------------------------
121+
-- Error Handling
122+
--------------------------------------------------------------------------------
123+
124+
||| Get last error message
125+
export
126+
%foreign "C:universal_chat_extractor_last_error, libuniversal_chat_extractor"
127+
prim__lastError : PrimIO Bits64
128+
129+
||| Retrieve last error as string
130+
export
131+
lastError : IO (Maybe String)
132+
lastError = do
133+
ptr <- primIO prim__lastError
134+
if ptr == 0
135+
then pure Nothing
136+
else pure (Just (prim__getString ptr))
137+
138+
||| Get error description for result code
139+
export
140+
errorDescription : Result -> String
141+
errorDescription Ok = "Success"
142+
errorDescription Error = "Generic error"
143+
errorDescription InvalidParam = "Invalid parameter"
144+
errorDescription OutOfMemory = "Out of memory"
145+
errorDescription NullPointer = "Null pointer"
146+
147+
--------------------------------------------------------------------------------
148+
-- Version Information
149+
--------------------------------------------------------------------------------
150+
151+
||| Get library version
152+
export
153+
%foreign "C:universal_chat_extractor_version, libuniversal_chat_extractor"
154+
prim__version : PrimIO Bits64
155+
156+
||| Get version as string
157+
export
158+
version : IO String
159+
version = do
160+
ptr <- primIO prim__version
161+
pure (prim__getString ptr)
162+
163+
||| Get library build info
164+
export
165+
%foreign "C:universal_chat_extractor_build_info, libuniversal_chat_extractor"
166+
prim__buildInfo : PrimIO Bits64
167+
168+
||| Get build information
169+
export
170+
buildInfo : IO String
171+
buildInfo = do
172+
ptr <- primIO prim__buildInfo
173+
pure (prim__getString ptr)
174+
175+
--------------------------------------------------------------------------------
176+
-- Callback Support
177+
--------------------------------------------------------------------------------
178+
179+
||| Callback function type (C ABI)
180+
public export
181+
Callback : Type
182+
Callback = Bits64 -> Bits32 -> Bits32
183+
184+
||| Register a callback
185+
export
186+
%foreign "C:universal_chat_extractor_register_callback, libuniversal_chat_extractor"
187+
prim__registerCallback : Bits64 -> AnyPtr -> PrimIO Bits32
188+
189+
||| Safe callback registration
190+
export
191+
registerCallback : Handle -> Callback -> IO (Either Result ())
192+
registerCallback h cb = do
193+
result <- primIO (prim__registerCallback (handlePtr h) (cast cb))
194+
pure $ case resultFromInt result of
195+
Just Ok => Right ()
196+
Just err => Left err
197+
Nothing => Left Error
198+
where
199+
resultFromInt : Bits32 -> Maybe Result
200+
resultFromInt 0 = Just Ok
201+
resultFromInt _ = Just Error
202+
203+
--------------------------------------------------------------------------------
204+
-- Utility Functions
205+
--------------------------------------------------------------------------------
206+
207+
||| Check if library is initialized
208+
export
209+
%foreign "C:universal_chat_extractor_is_initialized, libuniversal_chat_extractor"
210+
prim__isInitialized : Bits64 -> PrimIO Bits32
211+
212+
||| Check initialization status
213+
export
214+
isInitialized : Handle -> IO Bool
215+
isInitialized h = do
216+
result <- primIO (prim__isInitialized (handlePtr h))
217+
pure (result /= 0)

0 commit comments

Comments
 (0)