Skip to content

Commit 8fdef22

Browse files
Nic-dormanclaude
andcommitted
fix(php): correct FFI header signatures and result parsing
- Fix blocking wrapper function signatures to use RustBuffer *out_result pattern for functions returning records (scratchpad, register, graph entry, vault, archive operations) - Fix parseUploadResult to handle Arc<DataAddress> as 8-byte pointer instead of hex string - Fix PublicArchive/PrivateArchive addFile to capture returned handle (Rust immutable pattern returns new Arc<Self>) - Add 32-byte value helpers for register tests - Fix duplicate test method name in GraphEntryVaultArchiveTest - Update integration tests with proper assertions and skip markers Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent caac857 commit 8fdef22

File tree

12 files changed

+405
-152
lines changed

12 files changed

+405
-152
lines changed

php/ant_ffi/composer.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
"autoload": {
1717
"psr-4": {
1818
"AntFfi\\": "src/"
19-
}
19+
},
20+
"classmap": [
21+
"src/Types/"
22+
]
2023
},
2124
"autoload-dev": {
2225
"psr-4": {

php/ant_ffi/ffi/ant_ffi.h

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -138,24 +138,24 @@ void uniffi_ant_ffi_fn_func_client_pointer_put_blocking(void *client, void *poin
138138

139139
// Scratchpad Blocking
140140
void *uniffi_ant_ffi_fn_func_client_scratchpad_get_blocking(void *client, void *address, RustCallStatus *out_status);
141-
void uniffi_ant_ffi_fn_func_client_scratchpad_put_blocking(void *client, void *scratchpad, void *wallet, RustCallStatus *out_status);
141+
void uniffi_ant_ffi_fn_func_client_scratchpad_put_blocking(RustBuffer *out_result, void *client, void *scratchpad, void *wallet, RustCallStatus *out_status);
142142

143143
// Register Blocking
144144
void uniffi_ant_ffi_fn_func_client_register_get_blocking(RustBuffer *out_result, void *client, void *address, RustCallStatus *out_status);
145-
void *uniffi_ant_ffi_fn_func_client_register_create_blocking(void *client, void *owner, RustBuffer value, void *wallet, RustCallStatus *out_status);
145+
void uniffi_ant_ffi_fn_func_client_register_create_blocking(RustBuffer *out_result, void *client, void *owner, RustBuffer value, void *wallet, RustCallStatus *out_status);
146146
void uniffi_ant_ffi_fn_func_client_register_update_blocking(void *client, void *owner, RustBuffer value, void *wallet, RustCallStatus *out_status);
147147

148148
// Graph Entry Blocking
149149
void *uniffi_ant_ffi_fn_func_client_graph_entry_get_blocking(void *client, void *address, RustCallStatus *out_status);
150-
void uniffi_ant_ffi_fn_func_client_graph_entry_put_blocking(void *client, void *entry, void *wallet, RustCallStatus *out_status);
150+
void uniffi_ant_ffi_fn_func_client_graph_entry_put_blocking(RustBuffer *out_result, void *client, void *entry, void *wallet, RustCallStatus *out_status);
151151

152152
// Vault Blocking
153153
void *uniffi_ant_ffi_fn_func_client_vault_get_user_data_blocking(void *client, void *secret_key, RustCallStatus *out_status);
154-
void uniffi_ant_ffi_fn_func_client_vault_put_user_data_blocking(void *client, void *secret_key, void *wallet, void *user_data, RustCallStatus *out_status);
154+
void uniffi_ant_ffi_fn_func_client_vault_put_user_data_blocking(RustBuffer *out_result, void *client, void *secret_key, void *wallet, void *user_data, RustCallStatus *out_status);
155155

156156
// Archive Blocking
157157
void *uniffi_ant_ffi_fn_func_client_archive_get_public_blocking(void *client, void *address, RustCallStatus *out_status);
158-
void uniffi_ant_ffi_fn_func_client_archive_put_public_blocking(void *client, void *archive, void *wallet, RustCallStatus *out_status);
158+
void uniffi_ant_ffi_fn_func_client_archive_put_public_blocking(RustBuffer *out_result, void *client, void *archive, void *wallet, RustCallStatus *out_status);
159159

160160
// File Blocking
161161
void uniffi_ant_ffi_fn_func_client_file_upload_blocking(RustBuffer *out_result, void *client, RustBuffer path, void *wallet, RustCallStatus *out_status);
@@ -230,18 +230,18 @@ void uniffi_ant_ffi_fn_free_pointeraddress(void *ptr, RustCallStatus *out_status
230230
void *uniffi_ant_ffi_fn_clone_pointeraddress(void *ptr, RustCallStatus *out_status);
231231

232232
// PointerTarget
233-
void *uniffi_ant_ffi_fn_constructor_pointertarget_from_chunk_address(void *address, RustCallStatus *out_status);
234-
void *uniffi_ant_ffi_fn_constructor_pointertarget_from_graph_entry_address(void *address, RustCallStatus *out_status);
235-
void *uniffi_ant_ffi_fn_constructor_pointertarget_from_pointer_address(void *address, RustCallStatus *out_status);
236-
void *uniffi_ant_ffi_fn_constructor_pointertarget_from_scratchpad_address(void *address, RustCallStatus *out_status);
233+
void *uniffi_ant_ffi_fn_constructor_pointertarget_chunk(void *addr, RustCallStatus *out_status);
234+
void *uniffi_ant_ffi_fn_constructor_pointertarget_graph_entry(void *addr, RustCallStatus *out_status);
235+
void *uniffi_ant_ffi_fn_constructor_pointertarget_pointer(void *addr, RustCallStatus *out_status);
236+
void *uniffi_ant_ffi_fn_constructor_pointertarget_scratchpad(void *addr, RustCallStatus *out_status);
237+
void uniffi_ant_ffi_fn_method_pointertarget_to_hex(RustBuffer *out_result, void *ptr, RustCallStatus *out_status);
237238
void uniffi_ant_ffi_fn_free_pointertarget(void *ptr, RustCallStatus *out_status);
238239
void *uniffi_ant_ffi_fn_clone_pointertarget(void *ptr, RustCallStatus *out_status);
239240

240241
// NetworkPointer
241-
void *uniffi_ant_ffi_fn_constructor_networkpointer_new(void *owner, int64_t counter, void *target, RustCallStatus *out_status);
242+
void *uniffi_ant_ffi_fn_constructor_networkpointer_new(void *owner, uint64_t counter, void *target, RustCallStatus *out_status);
242243
void *uniffi_ant_ffi_fn_method_networkpointer_address(void *ptr, RustCallStatus *out_status);
243-
int64_t uniffi_ant_ffi_fn_method_networkpointer_counter(void *ptr, RustCallStatus *out_status);
244-
void *uniffi_ant_ffi_fn_method_networkpointer_owner(void *ptr, RustCallStatus *out_status);
244+
uint64_t uniffi_ant_ffi_fn_method_networkpointer_counter(void *ptr, RustCallStatus *out_status);
245245
void *uniffi_ant_ffi_fn_method_networkpointer_target(void *ptr, RustCallStatus *out_status);
246246
void uniffi_ant_ffi_fn_free_networkpointer(void *ptr, RustCallStatus *out_status);
247247
void *uniffi_ant_ffi_fn_clone_networkpointer(void *ptr, RustCallStatus *out_status);
@@ -255,13 +255,16 @@ void uniffi_ant_ffi_fn_free_scratchpadaddress(void *ptr, RustCallStatus *out_sta
255255
void *uniffi_ant_ffi_fn_clone_scratchpadaddress(void *ptr, RustCallStatus *out_status);
256256

257257
// Scratchpad
258-
void *uniffi_ant_ffi_fn_constructor_scratchpad_new(void *owner, int64_t content_type, RustBuffer data, int64_t counter, RustCallStatus *out_status);
258+
void *uniffi_ant_ffi_fn_constructor_scratchpad_new(void *owner, uint64_t data_encoding, RustBuffer unencrypted_data, uint64_t counter, RustCallStatus *out_status);
259259
void *uniffi_ant_ffi_fn_method_scratchpad_address(void *ptr, RustCallStatus *out_status);
260-
int64_t uniffi_ant_ffi_fn_method_scratchpad_counter(void *ptr, RustCallStatus *out_status);
261-
int64_t uniffi_ant_ffi_fn_method_scratchpad_content_type(void *ptr, RustCallStatus *out_status);
262-
void uniffi_ant_ffi_fn_method_scratchpad_data(RustBuffer *out_result, void *ptr, RustCallStatus *out_status);
263-
int8_t uniffi_ant_ffi_fn_method_scratchpad_is_valid(void *ptr, RustCallStatus *out_status);
260+
uint64_t uniffi_ant_ffi_fn_method_scratchpad_counter(void *ptr, RustCallStatus *out_status);
261+
uint64_t uniffi_ant_ffi_fn_method_scratchpad_data_encoding(void *ptr, RustCallStatus *out_status);
262+
void uniffi_ant_ffi_fn_method_scratchpad_encrypted_data(RustBuffer *out_result, void *ptr, RustCallStatus *out_status);
263+
void uniffi_ant_ffi_fn_method_scratchpad_decrypt_data(RustBuffer *out_result, void *ptr, void *sk, RustCallStatus *out_status);
264+
void uniffi_ant_ffi_fn_method_scratchpad_encrypted_data_hash(RustBuffer *out_result, void *ptr, RustCallStatus *out_status);
264265
void *uniffi_ant_ffi_fn_method_scratchpad_owner(void *ptr, RustCallStatus *out_status);
266+
void uniffi_ant_ffi_fn_method_scratchpad_scratchpad_hash(RustBuffer *out_result, void *ptr, RustCallStatus *out_status);
267+
void uniffi_ant_ffi_fn_func_scratchpad_verify(void *scratchpad, RustCallStatus *out_status);
265268
void uniffi_ant_ffi_fn_free_scratchpad(void *ptr, RustCallStatus *out_status);
266269
void *uniffi_ant_ffi_fn_clone_scratchpad(void *ptr, RustCallStatus *out_status);
267270

@@ -274,18 +277,18 @@ void uniffi_ant_ffi_fn_free_registeraddress(void *ptr, RustCallStatus *out_statu
274277
void *uniffi_ant_ffi_fn_clone_registeraddress(void *ptr, RustCallStatus *out_status);
275278

276279
// GraphEntryAddress
277-
void *uniffi_ant_ffi_fn_constructor_graphentryaddress_new(void *owner, RustCallStatus *out_status);
280+
void *uniffi_ant_ffi_fn_constructor_graphentryaddress_new(void *public_key, RustCallStatus *out_status);
278281
void *uniffi_ant_ffi_fn_constructor_graphentryaddress_from_hex(RustBuffer hex, RustCallStatus *out_status);
279-
void *uniffi_ant_ffi_fn_method_graphentryaddress_owner(void *ptr, RustCallStatus *out_status);
280282
void uniffi_ant_ffi_fn_method_graphentryaddress_to_hex(RustBuffer *out_result, void *ptr, RustCallStatus *out_status);
281283
void uniffi_ant_ffi_fn_free_graphentryaddress(void *ptr, RustCallStatus *out_status);
282284
void *uniffi_ant_ffi_fn_clone_graphentryaddress(void *ptr, RustCallStatus *out_status);
283285

284286
// GraphEntry
285-
void *uniffi_ant_ffi_fn_constructor_graphentry_new(void *owner, RustBuffer parents, RustBuffer content, RustCallStatus *out_status);
287+
void *uniffi_ant_ffi_fn_constructor_graphentry_new(void *owner, RustBuffer parents, RustBuffer content, RustBuffer descendants, RustCallStatus *out_status);
286288
void *uniffi_ant_ffi_fn_method_graphentry_address(void *ptr, RustCallStatus *out_status);
287-
void *uniffi_ant_ffi_fn_method_graphentry_owner(void *ptr, RustCallStatus *out_status);
288289
void uniffi_ant_ffi_fn_method_graphentry_content(RustBuffer *out_result, void *ptr, RustCallStatus *out_status);
290+
void uniffi_ant_ffi_fn_method_graphentry_parents(RustBuffer *out_result, void *ptr, RustCallStatus *out_status);
291+
void uniffi_ant_ffi_fn_method_graphentry_descendants(RustBuffer *out_result, void *ptr, RustCallStatus *out_status);
289292
void uniffi_ant_ffi_fn_free_graphentry(void *ptr, RustCallStatus *out_status);
290293
void *uniffi_ant_ffi_fn_clone_graphentry(void *ptr, RustCallStatus *out_status);
291294

@@ -311,14 +314,14 @@ void *uniffi_ant_ffi_fn_clone_archiveaddress(void *ptr, RustCallStatus *out_stat
311314

312315
// PublicArchive
313316
void *uniffi_ant_ffi_fn_constructor_publicarchive_new(RustCallStatus *out_status);
314-
void uniffi_ant_ffi_fn_method_publicarchive_add_file(void *ptr, RustBuffer path, void *data_address, void *metadata, RustCallStatus *out_status);
317+
void *uniffi_ant_ffi_fn_method_publicarchive_add_file(void *ptr, RustBuffer path, void *data_address, void *metadata, RustCallStatus *out_status);
315318
void uniffi_ant_ffi_fn_method_publicarchive_files(RustBuffer *out_result, void *ptr, RustCallStatus *out_status);
316319
void uniffi_ant_ffi_fn_free_publicarchive(void *ptr, RustCallStatus *out_status);
317320
void *uniffi_ant_ffi_fn_clone_publicarchive(void *ptr, RustCallStatus *out_status);
318321

319322
// PrivateArchive
320323
void *uniffi_ant_ffi_fn_constructor_privatearchive_new(RustCallStatus *out_status);
321-
void uniffi_ant_ffi_fn_method_privatearchive_add_file(void *ptr, RustBuffer path, void *data_map, void *metadata, RustCallStatus *out_status);
324+
void *uniffi_ant_ffi_fn_method_privatearchive_add_file(void *ptr, RustBuffer path, void *data_map, void *metadata, RustCallStatus *out_status);
322325
void uniffi_ant_ffi_fn_method_privatearchive_files(RustBuffer *out_result, void *ptr, RustCallStatus *out_status);
323326
void uniffi_ant_ffi_fn_free_privatearchive(void *ptr, RustCallStatus *out_status);
324327
void *uniffi_ant_ffi_fn_clone_privatearchive(void *ptr, RustCallStatus *out_status);
@@ -330,8 +333,10 @@ void uniffi_ant_ffi_fn_free_privatearchivedatamap(void *ptr, RustCallStatus *out
330333
void *uniffi_ant_ffi_fn_clone_privatearchivedatamap(void *ptr, RustCallStatus *out_status);
331334

332335
// Metadata
333-
void *uniffi_ant_ffi_fn_constructor_metadata_new(RustCallStatus *out_status);
334-
void *uniffi_ant_ffi_fn_constructor_metadata_with_size(uint64_t size, RustCallStatus *out_status);
336+
void *uniffi_ant_ffi_fn_constructor_metadata_new(uint64_t size, RustCallStatus *out_status);
337+
void *uniffi_ant_ffi_fn_constructor_metadata_with_timestamps(uint64_t size, uint64_t created, uint64_t modified, RustCallStatus *out_status);
335338
uint64_t uniffi_ant_ffi_fn_method_metadata_size(void *ptr, RustCallStatus *out_status);
339+
uint64_t uniffi_ant_ffi_fn_method_metadata_created(void *ptr, RustCallStatus *out_status);
340+
uint64_t uniffi_ant_ffi_fn_method_metadata_modified(void *ptr, RustCallStatus *out_status);
336341
void uniffi_ant_ffi_fn_free_metadata(void *ptr, RustCallStatus *out_status);
337342
void *uniffi_ant_ffi_fn_clone_metadata(void *ptr, RustCallStatus *out_status);

php/ant_ffi/src/Types/Archive.php

Lines changed: 77 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,15 @@ protected function cloneHandle(): CData
7878
final class Metadata extends NativeHandle
7979
{
8080
/**
81-
* Create new empty metadata.
81+
* Create metadata with a file size.
8282
*/
83-
public static function create(): self
83+
public static function create(int $size): self
8484
{
8585
$ffi = FFILoader::get();
8686
$status = $ffi->new('RustCallStatus');
8787

8888
$handle = $ffi->uniffi_ant_ffi_fn_constructor_metadata_new(
89+
$size,
8990
FFI::addr($status)
9091
);
9192

@@ -95,15 +96,29 @@ public static function create(): self
9596
}
9697

9798
/**
98-
* Create metadata with a file size.
99+
* Alias for create() for backwards compatibility.
99100
*/
100101
public static function withSize(int $size): self
102+
{
103+
return self::create($size);
104+
}
105+
106+
/**
107+
* Create metadata with timestamps.
108+
*
109+
* @param int $size File size in bytes
110+
* @param int $created Created timestamp (Unix seconds)
111+
* @param int $modified Modified timestamp (Unix seconds)
112+
*/
113+
public static function withTimestamps(int $size, int $created, int $modified): self
101114
{
102115
$ffi = FFILoader::get();
103116
$status = $ffi->new('RustCallStatus');
104117

105-
$handle = $ffi->uniffi_ant_ffi_fn_constructor_metadata_with_size(
118+
$handle = $ffi->uniffi_ant_ffi_fn_constructor_metadata_with_timestamps(
106119
$size,
120+
$created,
121+
$modified,
107122
FFI::addr($status)
108123
);
109124

@@ -130,6 +145,42 @@ public function size(): int
130145
return $result;
131146
}
132147

148+
/**
149+
* Get the created timestamp.
150+
*/
151+
public function created(): int
152+
{
153+
$ffi = FFILoader::get();
154+
$status = $ffi->new('RustCallStatus');
155+
156+
$result = $ffi->uniffi_ant_ffi_fn_method_metadata_created(
157+
$this->cloneForCall(),
158+
FFI::addr($status)
159+
);
160+
161+
RustBuffer::checkStatus($status);
162+
163+
return $result;
164+
}
165+
166+
/**
167+
* Get the modified timestamp.
168+
*/
169+
public function modified(): int
170+
{
171+
$ffi = FFILoader::get();
172+
$status = $ffi->new('RustCallStatus');
173+
174+
$result = $ffi->uniffi_ant_ffi_fn_method_metadata_modified(
175+
$this->cloneForCall(),
176+
FFI::addr($status)
177+
);
178+
179+
RustBuffer::checkStatus($status);
180+
181+
return $result;
182+
}
183+
133184
protected function freeHandle(): void
134185
{
135186
$ffi = FFILoader::get();
@@ -170,6 +221,9 @@ public static function create(): self
170221
/**
171222
* Add a file to the archive.
172223
*
224+
* Note: This returns a new archive with the file added (immutable pattern).
225+
* The current object is updated to point to the new archive.
226+
*
173227
* @param string $path The file path within the archive
174228
* @param DataAddress $dataAddress The address where the file data is stored
175229
* @param Metadata $metadata File metadata
@@ -180,7 +234,7 @@ public function addFile(string $path, DataAddress $dataAddress, Metadata $metada
180234
$status = $ffi->new('RustCallStatus');
181235

182236
$pathBuffer = RustBuffer::fromString($path);
183-
$ffi->uniffi_ant_ffi_fn_method_publicarchive_add_file(
237+
$newHandle = $ffi->uniffi_ant_ffi_fn_method_publicarchive_add_file(
184238
$this->cloneForCall(),
185239
$pathBuffer,
186240
$dataAddress->cloneForCall(),
@@ -189,6 +243,12 @@ public function addFile(string $path, DataAddress $dataAddress, Metadata $metada
189243
);
190244

191245
RustBuffer::checkStatus($status);
246+
247+
// The Rust method returns a new archive - update our handle
248+
// First free the old handle, then update to the new one
249+
$this->freeHandle();
250+
$this->handle = $newHandle;
251+
$this->disposed = false;
192252
}
193253

194254
/**
@@ -208,7 +268,7 @@ public function files(): string
208268

209269
RustBuffer::checkStatus($status);
210270

211-
$result = RustBuffer::toStringWithPrefix($resultBuffer);
271+
$result = RustBuffer::toString($resultBuffer);
212272
RustBuffer::free($resultBuffer);
213273

214274
return $result;
@@ -254,6 +314,9 @@ public static function create(): self
254314
/**
255315
* Add a file to the archive.
256316
*
317+
* Note: This returns a new archive with the file added (immutable pattern).
318+
* The current object is updated to point to the new archive.
319+
*
257320
* @param string $path The file path within the archive
258321
* @param DataMapChunk $dataMap The data map for the encrypted file
259322
* @param Metadata $metadata File metadata
@@ -264,7 +327,7 @@ public function addFile(string $path, DataMapChunk $dataMap, Metadata $metadata)
264327
$status = $ffi->new('RustCallStatus');
265328

266329
$pathBuffer = RustBuffer::fromString($path);
267-
$ffi->uniffi_ant_ffi_fn_method_privatearchive_add_file(
330+
$newHandle = $ffi->uniffi_ant_ffi_fn_method_privatearchive_add_file(
268331
$this->cloneForCall(),
269332
$pathBuffer,
270333
$dataMap->cloneForCall(),
@@ -273,6 +336,12 @@ public function addFile(string $path, DataMapChunk $dataMap, Metadata $metadata)
273336
);
274337

275338
RustBuffer::checkStatus($status);
339+
340+
// The Rust method returns a new archive - update our handle
341+
// First free the old handle, then update to the new one
342+
$this->freeHandle();
343+
$this->handle = $newHandle;
344+
$this->disposed = false;
276345
}
277346

278347
/**
@@ -292,7 +361,7 @@ public function files(): string
292361

293362
RustBuffer::checkStatus($status);
294363

295-
$result = RustBuffer::toStringWithPrefix($resultBuffer);
364+
$result = RustBuffer::toString($resultBuffer);
296365
RustBuffer::free($resultBuffer);
297366

298367
return $result;

0 commit comments

Comments
 (0)