capnweb_core/
lib.rs

1//! # Cap'n Web Core Protocol
2//!
3//! Core implementation of the [Cap'n Web protocol](https://github.com/cloudflare/capnweb),
4//! providing capability-based RPC with promise pipelining.
5//!
6//! ## Features
7//!
8//! - **Capability-based security**: Unforgeable object references with fine-grained access control
9//! - **Promise pipelining**: Chain dependent calls without waiting for intermediate results
10//! - **IL expression evaluation**: Execute complex operations with the Intermediate Language
11//! - **Wire protocol compliance**: Full compatibility with the official TypeScript implementation
12//!
13//! ## Quick Start
14//!
15//! ```rust,no_run
16//! use capnweb_core::{CapId, RpcTarget, RpcError, Value};
17//! use async_trait::async_trait;
18//! use serde_json::json;
19//!
20//! #[derive(Debug)]
21//! struct Calculator;
22//!
23//! #[async_trait]
24//! impl RpcTarget for Calculator {
25//!     async fn call(&self, method: &str, args: Vec<Value>) -> Result<Value, RpcError> {
26//!         match method {
27//!             "add" => {
28//!                 // Note: Value is from capnweb_core, not serde_json
29//!                 // In a real implementation, you'd need to convert between types
30//!                 Ok(Value::String("result".to_string()))
31//!             }
32//!             _ => Err(RpcError::not_found("method not found")),
33//!         }
34//!     }
35//!
36//!     async fn get_property(&self, _property: &str) -> Result<Value, RpcError> {
37//!         Err(RpcError::not_found("property access not implemented"))
38//!     }
39//! }
40//! ```
41//!
42//! ## Protocol Concepts
43//!
44//! ### Capabilities
45//! Capabilities are unforgeable references to remote objects. They provide secure,
46//! fine-grained access control without ambient authority.
47//!
48//! ### Promise Pipelining
49//! Calls can be chained on promises before they resolve, reducing round-trips:
50//!
51//! ```ignore
52//! let user = client.call(cap, "getUser", vec![user_id]);
53//! let profile = client.pipeline(&user, vec!["profile"], "load", vec![]);
54//! ```
55//!
56//! ### IL (Intermediate Language)
57//! The IL allows expressing complex operations that execute on the server:
58//!
59//! ```ignore
60//! let expr = ILExpression::if_expr(
61//!     ILExpression::var(0),
62//!     ILExpression::literal(json!("authenticated")),
63//!     ILExpression::literal(json!("anonymous"))
64//! );
65//! ```
66
67// Legacy modules (to be deprecated)
68pub mod codec;
69pub mod error;
70pub mod ids;
71pub mod il;
72pub mod il_executor;
73pub mod il_extended;
74pub mod msg;
75pub mod promise;
76pub mod promise_map;
77#[cfg(feature = "validation")]
78pub mod validate;
79
80// New Cap'n Web protocol implementation
81pub mod protocol;
82
83// Re-export legacy types for backward compatibility
84pub use codec::{decode_message, encode_message};
85pub use error::{ErrorCode, RpcError};
86pub use ids::{CallId, CapId, PromiseId};
87pub use il::{Op, Plan, Source};
88pub use il_executor::ILExecutor;
89pub use il_extended::{ILContext, ILError, ILExpression, ILOperation, ILPlan};
90pub use msg::{Message, Outcome, Target};
91pub use promise::{ArgValue, ExtendedTarget, PendingPromise, PromiseDependencyGraph};
92pub use promise_map::{MapOperation, PipelinedCall, PromiseMapExecutor};
93
94// Re-export official Cap'n Web wire protocol (primary)
95pub use protocol::{
96    capability_registry::{CapabilityRegistry, RegistrableCapability},
97    ids::{ExportId, ImportId},
98    tables::{ExportTable, ImportTable, Value},
99    wire::{parse_wire_batch, serialize_wire_batch, PropertyKey, WireExpression, WireMessage},
100};
101
102// Legacy protocol types
103pub use protocol::{expression::Expression, message::Message as LegacyMessage};
104
105// RPC Target trait for capability implementations
106pub use async_trait::async_trait;
107
108#[async_trait]
109pub trait RpcTarget: Send + Sync + std::fmt::Debug {
110    /// Call a method on this capability
111    async fn call(&self, method: &str, args: Vec<Value>) -> Result<Value, RpcError>;
112
113    /// Get a property from this capability
114    async fn get_property(&self, property: &str) -> Result<Value, RpcError>;
115}
116
117// Mock RPC target for testing
118#[cfg(test)]
119#[derive(Debug)]
120pub struct MockRpcTarget {}
121
122#[cfg(test)]
123impl MockRpcTarget {
124    pub fn new() -> Self {
125        Self {}
126    }
127}
128
129#[cfg(test)]
130impl Default for MockRpcTarget {
131    fn default() -> Self {
132        Self::new()
133    }
134}
135
136#[cfg(test)]
137#[async_trait]
138impl RpcTarget for MockRpcTarget {
139    async fn call(&self, method: &str, args: Vec<Value>) -> Result<Value, RpcError> {
140        Ok(Value::String(format!(
141            "Mock call to {} with {} args",
142            method,
143            args.len()
144        )))
145    }
146
147    async fn get_property(&self, property: &str) -> Result<Value, RpcError> {
148        Ok(Value::String(format!("Mock property {}", property)))
149    }
150}