Zum Inhalt springen

Getting Started

Dieser Inhalt ist noch nicht in deiner Sprache verfügbar.

Goal: a loadable plugin that the app recognises, in under 15 minutes. It will implement just enough to list one (empty) calendar.

  • Rust (stable) with the ability to build a cdylib (the default toolchain can).
  • The Aperio source tree, or at least the published plugin-sdk and cal-core crates, available as dependencies.
Cargo.toml
[package]
name = "my-plugin"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"] # produces a loadable shared library
[dependencies]
cal-core = { path = "../aperio/crates/cal-core" } # or the published crate
plugin-sdk = { path = "../aperio/crates/plugin-sdk" }
async-trait = "0.1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"

Write ordinary Rust. Implement Adapter (base) plus the feature traits you support — here just a minimal CalendarFeature that returns no calendars:

use async_trait::async_trait;
use cal_core::{
Adapter, AuthToken, Calendar, CalendarFeature, Capability,
Credentials, Result,
};
pub struct MyAdapter;
#[async_trait]
impl Adapter for MyAdapter {
async fn authenticate(&self, _c: Credentials) -> Result<AuthToken> {
Ok(AuthToken::default())
}
fn capabilities(&self) -> &[Capability] {
&[Capability::Calendar]
}
}
#[async_trait]
impl CalendarFeature for MyAdapter {
async fn list_calendars(&self) -> Result<Vec<Calendar>> {
Ok(vec![]) // a real plugin would call its provider here
}
// ... other CalendarFeature methods (see the template example)
}

The SDK macros turn your trait impl into the C ABI the host loads. You declare the lifecycle and the vtable; see The Rust SDK for the full pattern (declare_lifecycle!, the per-method ffi_* wrappers generated with cal_dispatch_helpers!, and the static *_VTABLE).

{
"id": "com.example.my-plugin",
"name": "My Plugin",
"version": "0.1.0",
"plugin_type": "adapter",
"capabilities": ["calendar"],
"abi_version": 3,
"min_app_version": "0.1.0",
"author": "You",
"description": "A minimal example calendar adapter.",
"signed": false
}

See the manifest reference for every field.

Terminal window
cargo build --release # produces target/release/{lib}my_plugin.{so,dll,dylib}

Package the shared library together with plugin.json into a .aperio archive, then install it from the app’s plugin settings and try it. The hello-world example is exactly this, complete.

  • Don’t want to hand-write each ffi_* wrapper? That’s what the Rust SDK macros are for.
  • Building a real calendar adapter? Start from the calendar adapter template.
  • Curious what crosses the boundary and why it stays compatible? Read The C ABI.