Skip to main content

resource

Attribute Macro resource 

#[resource]
Expand description

Turn a record’s #[action] methods into its replayable, published action vocabulary, and implement Resource for it.

ⓘ
#[resource(kind = "example.note", label = "Note")]
impl Note {
    /// Replace the note's text.
    #[action]
    pub fn edit(&mut self, #[param("Note text")] text: String) { self.body = text; }
}

Generates, per action, a parameter struct in a module named after the type (note::Edit { text }, with a JSON Schema derived from the parameter types), a variant of NoteAction carrying it, and Note::EDIT, an ActionRef views bind controls to and tests apply; then impl Resource. Field edits are a built-in variant.

An action method takes &mut self, optionally cx: &mut ActionCx (or cx: &ActionCx, for one that only reads it) and &mut Outbox<T> fields of the record (by field name: such an action reaches outside the document), then its parameters, and returns () or Result<(), impl Into<Refusal>>. Its public id is its name in kebab case unless #[action(id = "...")]; a parameter is published under its name unless #[param(name = "...")], and #[param("Description", example = value)] describes it.

An action whose first parameter is an item Id is also published on each item of the collection it acts on, with the id bound: the collection named like the parameter, or the record’s only one; #[action(item = field)] names it otherwise, and anything else does not compile.

Action options: label = "...", destructive (it deletes or overwrites: when Undo takes it back, as it does any change of the document alone, it runs at once and offers Undo; otherwise people confirm it, through any door), irreversible (it also loses what Undo cannot bring back, such as a secret every device forgets: a destructive one is confirmed even though Undo reverts its document change), housekeeping (a change about the record rather than to it, such as a read marker), external (content from outside, nobody’s undo step), local (an action of a record with a queue that queues nothing, so an undoable change rather than one reaching outside), field = "..." (an action that writes only that field is placed below it, so a grant on the field reaches it: someone who may only comment may add to the comments).

Resource options: label, params = module (the parameter module’s name), initialize = path (fn() -> Self, the deterministic genesis), seed = path (fn(&mut Self, &mut ActionCx), the creator’s first content), available = path (fn(&Self, module::Verb) -> Availability), children = path (fn(&Self) -> Vec<Derived<Self>>), child = path (fn(&Self, &str) -> Option<ResourceSpec>, a child the published page of children leaves out), search = path, scopes = path, read_content = path (fn(&Self, Option<&Id>) -> Result<serde_json::Value, String>), read_content_in_doc = path (the same read, fn(&Self, &Doc, Option<&Id>) -> ..., for one that needs the document itself), facts = path (fn(&Self) -> Result<serde_json::Value, String>, the compact summary Resource::facts states) and views = path.