Skip to main content

Crate standard_plugin

Crate standard_plugin 

Source
Expand description

Write Standard Code plugins in Rust.

Every plugin is a wasm component against the WIT package standard:plugin@2.0.0, built for wasm32-wasip2. This crate wraps the generated bindings in a safe API:

The account interfaces (values, live, events, calls, config, secrets, account) are shared by both. Every call the plugin’s manifest grants do not cover returns Error::GrantDenied.

A UI plugin is #![no_std] (the std library would import the WASI CLI world, which a viewer does not offer); alloc is available and this crate’s default runtime feature supplies the allocator and panic handler. A UI plugin, in full:

ⓘ
//! A sidebar card: the time since the viewer started and a bar of the
//! seconds. It repaints once a second and only while the card is visible.
//!
//! Manifest (`bundle/standard-plugin.json`):
//!
//! ```json
//! {
//!   "apiVersion": 2, "kind": "ui", "id": "clock-card", "version": "0.1.0",
//!   "module": "clock_card.wasm",
//!   "surfaces": [{ "id": "card", "anchor": "sidebar.card", "model": "cells", "height": 2 }],
//!   "grants": {}
//! }
//! ```
#![no_std]

use standard_plugin::prelude::*;

#[standard_plugin::ui]
struct ClockCard {
    card: Surface<Cells>,
    shown: Option<u64>,
}

impl UiPlugin for ClockCard {
    fn activate(_cx: &mut Context) -> Self {
        Self {
            card: Surface::new("card"),
            shown: None,
        }
    }

    fn frame(&mut self, frame: &Frame) {
        let second = frame.now_ms() / 1000;
        if self.shown != Some(second) {
            self.shown = Some(second);
            let (cols, _) = self.card.size();
            let time = format!(
                "{:02}:{:02}:{:02}",
                second / 3600 % 24,
                second / 60 % 60,
                second % 60
            );
            self.card.text(0, 0, &time, Style::fg(Colour::FG).bold());
            let fraction = (second % 60) as f32 / 60.0;
            let track = Style::fg(Colour::RECEDE_FG);
            self.card.bar(
                Area::new(0, 1, cols, 1),
                fraction,
                Style::fg(Colour::ACCENT),
                track,
            );
            // Publishes only the cells that changed.
            let _ = self.card.commit();
        }
        // The next second boundary: an idle viewer wakes once a second.
        frame.wake_at((second + 1) * 1000);
    }

    fn event(&mut self, event: Event, _cx: &mut Context) {
        if let Event::Resize { .. } = event {
            // The card has a new, empty buffer: repaint on the next frame.
            self.shown = None;
        }
    }
}

More: the guide pages (the same Markdown files are this crate’s docs/ directory, and standard-plugin guide prints them), and the compiled examples in this crate’s examples/ directory. testing (on non-wasm targets) runs a plugin against an in-process host in ordinary cargo test.

Re-exports§

pub use api::Json;
pub use api::Target;
pub use api::account;
pub use api::calls;
pub use api::calls;
pub use api::capabilities;
pub use api::claims;
pub use api::claims;
pub use api::config;
pub use api::events;
pub use api::events;
pub use api::health;
pub use api::live;
pub use api::live;
pub use api::secrets;
pub use api::url;
pub use api::values;
pub use api::values;
pub use api::view;
pub use draw::Area;
pub use draw::Image;
pub use draw::Shapes;
pub use draw::font;
pub use surface::AnySurface;
pub use surface::AnySurfaceMut;
pub use surface::Cell;
pub use surface::Cells;
pub use surface::Instances;
pub use surface::Pixels;
pub use surface::Surface;
pub use libm;

Modules§

api
The account interfaces shared by UI and daemon plugins, and the viewer interfaces of UI plugins.
daemon
Daemon plugins: run inside standardd on the machines the plugin is enabled on, never render, and may reach the machine through granted system interfaces (process, watch, panes; with the wasi feature, files, sockets and HTTP).
draw
Vector shapes drawn into a plugin’s own surface buffer, in either model.
guide
The guides, as pages of this documentation. The same Markdown files are this crate’s docs/ directory, where links between guides resolve, and standard-plugin guide prints them for the SDK version a plugin’s Cargo.lock resolves.
prelude
What most plugins import: use standard_plugin::prelude::*;.
sources
The sources this SDK version is built from, for tools: the standard-plugin CLI checks components against sources::WIT and scaffolds new plugins from the examples, so both always match the SDK the new plugin depends on.
surface
Surfaces: typed views over the double-buffered shared buffer a UI plugin paints and the viewer samples.
testing
Run a plugin under cargo test, against an in-process host.

Structs§

Attrs
Cell attribute bits.
Context
What a plugin is called with besides a frame: its configuration, and handles to every interface.
Frame
One frame callback.
Geometry
The size a surface currently has. cols/rows are cells; px_w/px_h the pixel size of the graphics model (zero while the viewer has no pixel geometry); cell_px_w/cell_px_h the pixel size of one cell.
Key
A key on the surface with input focus.
Modifiers
Modifier keys held during a key or pointer event.
Pointer
The pointer over one of the plugin’s surfaces.
Rect
A rectangle in cells (cell model) or pixels (graphics model).
Rgba
One RGBA8 pixel of the graphics model (straight, not premultiplied, alpha). In the buffer: the bytes r, g, b, a.
Style
How a cell paints: foreground, background, attributes.
ThemeSlot
A theme colour slot: the viewer resolves it to its current theme, so a plugin follows the user’s terminal colours and “receded” (grayed out) text stays readable on every background.

Enums§

Button
Colour
A cell colour. Encoded in the buffer as a u32 whose top byte is the model:
Error
Why a host call or a surface operation did not run.
Event
What the host tells a plugin besides frames.
KeyCode
Which key. A character key is the character it types; the named keys are the WIT’s vocabulary. Escape never arrives: it closes the surface.
KeyPhase
PointerKind
Power
Whether the viewer’s machine is saving power.

Traits§

UiPlugin
A UI plugin: one instance runs in every viewer on the account.

Functions§

recede
rgb blended percent of the way toward toward (both 0xRRGGBB), channel by channel: the viewer’s recede. With the theme’s background as toward it is “grayed out” (see crate::view::Theme::recede).

Type Aliases§

Result
Result<T, Error>.

Attribute Macros§

daemon
Exports the annotated type, which implements daemon::DaemonPlugin, as the component’s daemon-plugin world. Exports the annotated type, which implements standard_plugin::daemon::DaemonPlugin, as the plugin’s daemon-plugin world.
ui
Exports the annotated type, which implements UiPlugin, as the component’s ui-plugin world. Put it on the plugin’s struct or enum, or on its impl UiPlugin for ... block; once per plugin crate. Exports the annotated type, which implements standard_plugin::UiPlugin, as the plugin’s ui-plugin world.