feat(sdk): add Java and Ruby SDK wrappers over C FFI

Java SDK: JNI bindings to libquicproquo_ffi with QpqClient class,
Gradle build, and exception hierarchy matching Kotlin SDK.

Ruby SDK: FFI gem wrapping libquicproquo_ffi with Client class,
block-form auto-disconnect, gemspec for RubyGems publishing,
and example script.
This commit is contained in:
2026-03-04 21:00:20 +01:00
parent 3f5a3a5ac8
commit 12717979ba
15 changed files with 619 additions and 0 deletions

82
sdks/ruby/README.md Normal file
View File

@@ -0,0 +1,82 @@
# QuicProQuo Ruby SDK
Ruby FFI gem wrapping `libquicproquo_ffi` for the quicproquo E2E encrypted messenger.
## Prerequisites
- Ruby 3.1+
- `libquicproquo_ffi` built for the target platform
## Installation
```sh
gem install quicproquo
```
Or add to your Gemfile:
```ruby
gem "quicproquo"
```
## Building the Native Library
```sh
cargo build --release -p quicproquo-ffi
```
Set `QPQ_LIB_PATH` if the library is not in the default search path.
## Usage
```ruby
require "quicproquo"
# Block form (auto-disconnect)
QuicProQuo::Client.open("127.0.0.1:5001", ca_cert: "ca.pem") do |client|
client.login("alice", "secret")
client.send("bob", "hello from Ruby!")
messages = client.receive(timeout_ms: 5000)
messages.each { |msg| puts msg }
end
# Manual lifecycle
client = QuicProQuo::Client.new("127.0.0.1:5001", ca_cert: "ca.pem")
client.login("alice", "secret")
client.send("bob", "hello")
client.disconnect
```
## API
| Method | Description |
|---|---|
| `Client.new(server, ca_cert:, server_name:)` | Connect to server |
| `Client.open(server, **opts) { \|c\| ... }` | Connect with auto-disconnect |
| `client.login(username, password)` | OPAQUE authentication |
| `client.send(recipient, message)` | Send message by username |
| `client.receive(timeout_ms: 5000)` | Receive pending messages |
| `client.disconnect` | Disconnect |
| `client.connected?` | Connection status |
## Error Handling
```ruby
begin
client.login("alice", "wrong")
rescue QuicProQuo::AuthError => e
puts "Auth failed: #{e.message}"
rescue QuicProQuo::TimeoutError => e
puts "Timeout: #{e.message}"
rescue QuicProQuo::Error => e
puts "Error: #{e.message}"
end
```
## Structure
- `lib/quicproquo/client.rb` -- High-level client
- `lib/quicproquo/ffi_bindings.rb` -- FFI function declarations
- `lib/quicproquo/errors.rb` -- Exception classes
- `examples/demo.rb` -- Usage example