1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//! Native Cufflink services: extensions written in Rust that WASM services
//! call through `ext_call`.
//!
//! A native service is a binary whose `main` names the service and the
//! extensions it provides, each with the services allowed to call it:
//!
//! ```no_run
//! use cufflink_native::prelude::*;
//!
//! struct GoogleToken;
//!
//! impl Extension for GoogleToken {
//! fn call(&self, ctx: &CallContext, payload: Value) -> Result<Value> {
//! let scope = payload["scope"].as_str().ok_or("scope is required")?;
//! Ok(json!({ "token": scope, "tenant": ctx.tenant }))
//! }
//! }
//!
//! fn main() -> std::process::ExitCode {
//! cufflink_native::service("ext-google")
//! .extension("google.token", GoogleToken, ["reports-service"])
//! .run()
//! }
//! ```
//!
//! [`Service::run`] prints the service's manifest under `--emit-manifest`
//! (what `cufflink deploy` reads) and otherwise serves the Unix socket the
//! extension runner starts it with. [`Service::run_nats`] serves the same
//! extensions straight from NATS, as a provider the project runs itself.
//!
//! Each call runs on the blocking pool with the caller's [`CallContext`]
//! and is given up at its [deadline](CallDeadline::deadline). Besides the
//! codes of an extension's own [`ExtError`]s, a call fails with
//! `not_found` (no such extension), `timeout` (the deadline passed),
//! `panic` (the extension panicked), `invalid` (a malformed call, or on
//! NATS one whose body does not match its subject), `unsupported_protocol`
//! (a caller speaking another protocol), `unavailable` (the service is
//! shutting down) or `too_large` (a reply over the NATS server's maximum
//! payload). On NATS, a call whose deadline has passed gets no reply.
pub use NatsAuth;
pub use CallContext;
pub use CallDeadline;
pub use ;
pub use ;
pub use ;
pub use SocketServer;
use Value;
/// An extension: what answers the calls made to one name.
///
/// `call` runs on the blocking pool, so it may block; closures and
/// functions of the same signature are extensions too.
/// What an extension needs in scope.