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 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
//! # Webwire command-line Interface //! //! [![Crates.io](https://img.shields.io/crates/v/webwire-cli)](https://crates.io/crates/webwire-cli) //! [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/webwire/webwire-cli/Rust)](https://github.com/webwire/webwire-cli/actions) //! //! [![Discord Chat](https://img.shields.io/discord/726922033039933472?label=Discord+Chat&color=%23677bc4&logo=discord&logoColor=white&style=for-the-badge)](https://discord.gg/jjD6aWG) //! //! ![webwire logo](https://webwire.dev/logo.svg) //! //! Webwire is a **contract-first API system** which features an //! interface description language a network protocol and //! code generator for both servers and clients. //! //! This repository contains the the **command-line interface** used //! to validate Webwire IDL files and generate code and documentation. //! //! To learn more about webwire in general please visit the documentation //! repository [webwire/webwire-docs](https://github.com/webwire/webwire-docs). //! //! # Example //! //! The following example assumes a Rust server and a TypeScript client. Webwire //! is by no means limited to those two but those languages show the potential of //! webwire best. //! //! Given the following IDL file: //! //! ```webwire //! struct HelloRequest { //! name: String, //! } //! //! struct HelloResponse { //! message: String, //! } //! //! service Hello { //! hello: HelloRequest -> HelloResponse //! } //! ``` //! //! The server and client files can be generated using the code generator: //! //! ```bash //! $ webwire gen rust < api/chat.ww > server/src/api.rs //! $ webwire gen ts < api/chat.ww > client/src/api.ts //! ``` //! //! A Rust server implementation for the given code would look like this: //! //! ```rust,ignore //! use std::net::SocketAddr; //! use std::sync::{Arc}; //! //! use async_trait::async_trait; //! //! use ::api::chat; //! //! use ::webwire::server::hyper::MakeHyperService; //! use ::webwire::server::session::{Auth, AuthError}; //! use ::webwire::{Response, Router, Server, ConsumerError}; //! //! struct ChatService { //! #[allow(dead_code)] //! session: Arc<Session>, //! server: Arc<Server<Session>>, //! } //! //! #[async_trait] //! impl chat::Server<Session> for ChatService { //! async fn send(&self, message: &chat::Message) -> Response<Result<(), chat::SendError>> { //! let client = chat::ClientConsumer(&*self.server); //! assert!(matches!(client.on_message(message).await, Err(ConsumerError::Broadcast))); //! Ok(Ok(())) //! } //! } //! //! #[derive(Default)] //! struct Session {} //! //! struct Sessions {} //! //! impl Sessions { //! pub fn new() -> Self { //! Self {} //! } //! } //! //! #[async_trait] //! impl webwire::SessionHandler<Session> for Sessions { //! async fn auth(&self, _auth: Option<Auth>) -> Result<Session, AuthError> { //! Ok(Session::default()) //! } //! async fn connect(&self, _session: &Session) {} //! async fn disconnect(&self, _session: &Session) {} //! } //! //! #[tokio::main] //! async fn main() { //! // Create session handler //! let session_handler = Sessions::new(); //! //! // Create service router //! let router = Arc::new(Router::<Session>::new()); //! //! // Create webwire server //! let server = Arc::new(webwire::server::Server::new( //! session_handler, //! router.clone(), //! )); //! //! // Register services //! router.service(chat::ServerProvider({ //! let server = server.clone(); //! move |session| ChatService { //! session, //! server: server.clone(), //! } //! })); //! //! // Start hyper service //! let addr = SocketAddr::from(([0, 0, 0, 0], 2323)); //! let make_service = MakeHyperService { server }; //! let server = hyper::Server::bind(&addr).serve(make_service); //! //! if let Err(e) = server.await { //! eprintln!("server error: {}", e); //! } //! } //! ``` //! //! A TypeScript client using the generated code would look like that: //! //! ```typescript //! import { Client } from 'webwire' //! import api from 'api' // this is the generated code //! //! let client = new Client('http://localhost:8000/', [ //! api.chat.ClientProvider({ //! async on_message(message) { //! console.log("Message received:", message) //! } //! }) //! ]) //! //! assert(await client.connect()) //! //! let chat = api.chat.ServerConsumer(client) //! let response = await chat.message({ text: "Hello world!" }) //! //! assert(response.Ok === null) //! ``` //! //! ## License //! //! Licensed under either of //! //! - Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0)> //! - MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT)> //! //! at your option. pub mod codegen; pub mod common; pub mod idl; pub mod schema;