Skip to content

feat(larod): Add safe Rust bindings#230

Draft
vsem-azamat wants to merge 28 commits intoAxisCommunications:mainfrom
vsem-azamat:feature/larod-completion
Draft

feat(larod): Add safe Rust bindings#230
vsem-azamat wants to merge 28 commits intoAxisCommunications:mainfrom
vsem-azamat:feature/larod-completion

Conversation

@vsem-azamat
Copy link
Copy Markdown

@vsem-azamat vsem-azamat commented Mar 11, 2026

Safe Rust wrapper for the larod C API

Covers connection management, model loading/retrieval, tensor allocation, job execution, device enumeration, and parameter maps.

Important points:

  • Still in a progress and is a draft
  • Im not too experienced, but I need it and would like to use it
  • I try to avoid mistakes that I had here (PR feat(vdo): Add safe Rust bindings for VDO API #223)
  • Branched from feature/vdo-completion. Will rebase onto main once that merges.

Issue ticket number and link

  • N/A

Checklist before requesting a review

  • I have performed a self-review of my own code
  • I have verified that the code builds perfectly fine on my local system
  • I have added tests that prove my fix is effective or that my feature works
  • I have commented my code, particularly in hard-to-understand areas
  • I have verified that my code follows the style already available in the repository
  • I have made corresponding changes to the documentation

vsem-azamat and others added 28 commits December 28, 2025 15:54
Safe wrappers over vdo-sys with builder pattern for stream creation,
iterator-based frame capture, and automatic resource cleanup.

Tested on device: YUV, JPEG, H.264, H.265 formats work correctly.
Address all review comments. Fix GObject leak in Stream::drop.

- Consume-by-value ownership: start(self), stop(self), unref(self)
- Replace Iterator with next_buffer() -> Result
- Merge Frame into StreamBuffer (VdoBuffer = VdoFrame)
- Extract Map to separate module, keys as &CStr
- Add Resolution enum, remove buffer_strategy, rename to custom_timestamp_us
- Replace as_mut_slice with data_copy(), file_descriptor() returns Result

Tested: cargo clippy clean, 33/33 tests pass on Artpec-9 device.
…ct-test

Replace `use vdo_sys::*` with explicit type imports and `vdo_sys::`-qualified
function/constant calls at call sites. This addresses the PR review feedback
about avoiding glob imports. Also adds the missing VDO_ERROR_NO_VIDEO error
code and adopts expect-test for display/formatting tests.
- Clamp size to capacity in data_copy to prevent out-of-bounds reads
- Replace debug_assert with assert in unsafe constructors (from_ptr, from_raw)
- Document BorrowedFd lifetime constraints on file_descriptor()
- Fix double vdo_stream_stop by delegating to Drop
- Add Error::InvalidFd instead of overloading NullPointer for bad fds
- Return Option<usize> from header_size() for negative (no header) values
- Fix from_gerror safety comment to match actual code order
- Add Debug for Map and CStringPtr, Deref<Target=CStr> for CStringPtr
- Use explicit ptr::null::<c_char>(), comment as_ptr GLib convention
Return RawFd instead of BorrowedFd and mark the method unsafe.
BorrowedFd allowed callers to call try_clone_to_owned() in safe code,
which could lead to fd aliasing and use-after-close when VDO unrefs
the buffer.
drop() achieves the same result and is idiomatic Rust.
GLib treats any nonzero gboolean as true, not just GTRUE (1).
Using != GTRUE could misclassify a valid success value like 2 as failure.
Previously Drop always called vdo_stream_stop, even on streams that were
never started or where start() failed. This relied on undocumented VDO
idempotency. Now a `started` flag ensures stop is only called on streams
that were actually started successfully.
mem::forget(self) was called before the FFI unref call, so on failure
the buffer was permanently leaked with Drop already suppressed. Move
mem::forget after the success check so Drop can retry cleanup on error.
Previously Drop only logged when a GError was present, silently ignoring
GFALSE returns without an error object. Now logs in both cases.
- Remove dead zero-arg arm from try_func! macro
- Use != GFALSE instead of != 0 in is_last_buffer for consistency
- Remove public Default derive from VdoError (code=0 misleadingly
  maps to VDO_ERROR_UNKNOWN; only used internally in from_gerror)
- Add production warning to Map::dump() doc comment
VdoFormat wraps c_int (i32) but was stored via set_u32, which would
wrap VDO_FORMAT_NONE (-1) to u32::MAX. Added Map::set_i32/get_i32
and switched the builder to use set_i32 for format.

Reworded Send safety comments - the justification is exclusive
ownership and no thread-pinning requirement, not absence of Sync.
VdoFormat is c_int in bindgen, but VDO actually expects uint32
for the format key. Using set_i32 causes VDO to ignore the value.
Phase 1 implementation wrapping larod-sys with safe Rust types:
- Connection, Device, Model, Map, Tensors, JobRequest, Error
- Correct ownership/lifetime model with double/triple-pointer Drop
- All P0 function groups covered (sync inference workflow)
…ce tests

- Tensors::iter()/iter_mut() with IntoIterator, ExactSizeIterator, FusedIterator
- TensorMut now has all read-only accessors matching TensorRef
- Device tests behind `device-tests` feature flag
- Full error code coverage in unit tests (all 16 codes)
…ovements

Async model loading (load_model_async → ModelFuture), async job execution
(run_async → JobCompletion), model retrieval (get_model, models), and
from_raw_borrowed for callback-owned errors.
…fety

Remove async load/run APIs (overengineering for typical load-once + sync
inference workflow). Fix Send soundness for Tensors and JobRequest by
storing raw connection pointer instead of &Connection, avoiding the
Connection: Sync requirement. Apply PR AxisCommunications#223 review feedback: rename
Map::new to try_new, add SAFETY comments on unsafe blocks, fix error
handling to use from_utf8_lossy. Harden Drop impls to free larodError
even on success, fix panic safety in devices()/models() array handling,
add #[must_use] to OwnedTensorPtrs, fix PhantomData invariance in
JobRequest.
@socket-security
Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedcargo/​expect-test@​1.5.19910093100100

View full report

@vsem-azamat vsem-azamat changed the title Feature/larod completion feat(larod): Add save Rust bindings Mar 11, 2026
@vsem-azamat vsem-azamat changed the title feat(larod): Add save Rust bindings feat(larod): Add safe Rust bindings Mar 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants