mirror of
https://github.com/zap-proto/rust.git
synced 2026-10-30 15:04:23 +00:00
Cap'n Proto was the canonical name for this Rust implementation. The
ZAP rebrand had only been applied as a directory rename so far —
crate names, schema file extensions, import paths, and binaries all
still said `capnp` / `capnpc`. This commit makes the rebrand real.
Workspace renames:
- crate capnp/ → zap/ (name = "zap")
- crate capnpc/ → zapc/ (name = "zapc")
- crate capnp-futures/ → zap-futures/
- crate capnp-rpc/ → zap-rpc/
Source-file renames:
- *_capnp.rs → *_zap.rs (~12 files: schema_zap.rs, rpc_zap.rs, etc.)
- capnpc-rust.rs → zapc-rust.rs (the codegen binary entry point)
- *.capnp → *.zap (33 schema files)
Identifier renames across the workspace (96 files rewritten):
- `use capnp::` → `use zap::`
- `extern crate capnp` → `extern crate zap`
- `capnp::generated_code!` → `zap::generated_code!`
- `capnp::traits::Owned` → `zap::traits::Owned`
- `capnp::message::...` → `zap::message::...`
- `capnp::Error/Result` → `zap::Error/Result`
- `capnp::Word` → `zap::Word`
- `capnp::primitive_list` → `zap::primitive_list`
- `capnp::any_pointer` → `zap::any_pointer`
- (etc. — see python script in commit history for full list)
Cargo.toml dep keys:
- `capnp = { path = ... }` → `zap = { path = ... }`
- `[dependencies.capnp]` → `[dependencies.zap]`
- `capnpc = { ... }` → `zapc = { ... }`
- Per-crate name= field and bin = "capnpc-rust" → "zapc"
Schema header strip:
- `using Cxx = import "/capnp/c++.capnp";` lines removed (C++ binding
hints; Rust output doesn't need them, and they referenced a system
/usr/include path we don't ship)
- `$Cxx.namespace("capnp::...")` annotations removed
Build-time decoupling for the benchmark:
- Pre-generated `carsales_zap.rs`, `catrank_zap.rs`, `eval_zap.rs` are
now committed in benchmark/. benchmark/build.rs just copies them
into OUT_DIR instead of invoking the schema compiler at build time.
- benchmark/Cargo.toml drops the [build-dependencies] zapc entry.
Building the benchmark needs ONLY the `zap` runtime crate; no
schema-compiler binary, no plugin, no shell-out.
To regenerate the schema-bound .rs from .zap (developer-only step):
cargo build --release --bin zapc
ln -sf zapc target/release/capnpc-rust # plugin discovery name
cd benchmark && PATH=../target/release:$PATH \
capnp compile -orust eval.zap catrank.zap carsales.zap
The `capnp` tool here is the upstream C++ schema-text parser — only
used as a parser frontend at codegen time, never linked into the
benchmark binary. Runtime + build = 100% zap/zapc only.
Verified by:
cargo tree -p benchmark --release → no capnp dep
grep -rE 'capnp|Capnp|CAPNP' . → 0 hits in active source
cargo build -p benchmark --release → clean build, no system tool
bash ./benchmark/bench.sh quick → runs end-to-end
Other workspace members (fill_random_values, addressbook,
wasm-hello-world, capnpc/test fixtures) still use build.rs schema
compilation at build time; they require a `zap` binary in PATH.
That's pre-existing — the upstream Cap'n Proto Rust workspace had the
same requirement against the `capnp` binary. Out of scope for this PR.
121 lines
4.7 KiB
Plaintext
121 lines
4.7 KiB
Plaintext
# Copyright (c) 2013, Kenton Varda <[email protected]>
|
|
# All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions are met:
|
|
#
|
|
# 1. Redistributions of source code must retain the above copyright notice, this
|
|
# list of conditions and the following disclaimer.
|
|
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
# this list of conditions and the following disclaimer in the documentation
|
|
# and/or other materials provided with the distribution.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
@0x85150b117366d14b;
|
|
|
|
interface Calculator {
|
|
# A "simple" mathematical calculator, callable via RPC.
|
|
#
|
|
# But, to show off ZAP, we add some twists:
|
|
#
|
|
# - You can use the result from one call as the input to the next
|
|
# without a network round trip. To accomplish this, evaluate()
|
|
# returns a `Value` object wrapping the actual numeric value.
|
|
# This object may be used in a subsequent expression. With
|
|
# promise pipelining, the Value can actually be used before
|
|
# the evaluate() call that creates it returns!
|
|
#
|
|
# - You can define new functions, and then call them. This again
|
|
# shows off pipelining, but it also gives the client the
|
|
# opportunity to define a function on the client side and have
|
|
# the server call back to it.
|
|
#
|
|
# - The basic arithmetic operators are exposed as Functions, and
|
|
# you have to call getOperator() to obtain them from the server.
|
|
# This again demonstrates pipelining -- using getOperator() to
|
|
# get each operator and then using them in evaluate() still
|
|
# only takes one network round trip.
|
|
|
|
evaluate @0 (expression :Expression) -> (value :Value);
|
|
# Evaluate the given expression and return the result. The
|
|
# result is returned wrapped in a Value interface so that you
|
|
# may pass it back to the server in a pipelined request. To
|
|
# actually get the numeric value, you must call read() on the
|
|
# Value -- but again, this can be pipelined so that it incurs
|
|
# no additional latency.
|
|
|
|
struct Expression {
|
|
# A numeric expression.
|
|
|
|
union {
|
|
literal @0 :Float64;
|
|
# A literal numeric value.
|
|
|
|
previousResult @1 :Value;
|
|
# A value that was (or, will be) returned by a previous
|
|
# evaluate().
|
|
|
|
parameter @2 :UInt32;
|
|
# A parameter to the function (only valid in function bodies;
|
|
# see defFunction).
|
|
|
|
call :group {
|
|
# Call a function on a list of parameters.
|
|
function @3 :Function;
|
|
params @4 :List(Expression);
|
|
}
|
|
}
|
|
}
|
|
|
|
interface Value {
|
|
# Wraps a numeric value in an RPC object. This allows the value
|
|
# to be used in subsequent evaluate() requests without the client
|
|
# waiting for the evaluate() that returns the Value to finish.
|
|
|
|
read @0 () -> (value :Float64);
|
|
# Read back the raw numeric value.
|
|
}
|
|
|
|
defFunction @1 (paramCount :Int32, body :Expression)
|
|
-> (func :Function);
|
|
# Define a function that takes `paramCount` parameters and returns the
|
|
# evaluation of `body` after substituting these parameters.
|
|
|
|
interface Function {
|
|
# An algebraic function. Can be called directly, or can be used inside
|
|
# an Expression.
|
|
#
|
|
# A client can create a Function that runs on the server side using
|
|
# `defFunction()` or `getOperator()`. Alternatively, a client can
|
|
# implement a Function on the client side and the server will call back
|
|
# to it. However, a function defined on the client side will require a
|
|
# network round trip whenever the server needs to call it, whereas
|
|
# functions defined on the server and then passed back to it are called
|
|
# locally.
|
|
|
|
call @0 (params :List(Float64)) -> (value :Float64);
|
|
# Call the function on the given parameters.
|
|
}
|
|
|
|
getOperator @2 (op :Operator) -> (func :Function);
|
|
# Get a Function representing an arithmetic operator, which can then be
|
|
# used in Expressions.
|
|
|
|
enum Operator {
|
|
add @0;
|
|
subtract @1;
|
|
multiply @2;
|
|
divide @3;
|
|
}
|
|
}
|