Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: updates for return types for examples actix-web, tide, serenity, tower #892

Merged
merged 17 commits into from Oct 28, 2023
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
52 changes: 52 additions & 0 deletions codegen/src/lib.rs
Expand Up @@ -6,13 +6,65 @@ mod shuttle_main;
use proc_macro::TokenStream;
use proc_macro_error::proc_macro_error;

/// Setups up the `shuttle_runtime` to be executed. Allows
/// for user to setup a runtime without needing to explicitly
/// create one.
jonaro00 marked this conversation as resolved.
Show resolved Hide resolved
///
/// # Example
///
/// ```
/// #[shuttle_runtime::main]
/// async fn entry_point() {
/// todo!();
/// }
jonaro00 marked this conversation as resolved.
Show resolved Hide resolved
/// ```
#[cfg(feature = "frameworks")]
#[proc_macro_error]
#[proc_macro_attribute]
pub fn main(attr: TokenStream, item: TokenStream) -> TokenStream {
shuttle_main::r#impl(attr, item)
}

/// Setups up a `shuttle_app` to be generated. Allows
/// for user to setup a `next` application.
jonaro00 marked this conversation as resolved.
Show resolved Hide resolved
///
/// # Example
///
/// ```
/// shuttle_next::app! {
/// use futures::TryStreamExt;
/// use tracing::debug;
/// use shuttle_next::body::StreamBody;
/// use shuttle_next::extract::BodyStream;
/// use shuttle_next::response::{Response, IntoResponse};
///
/// #[shuttle_next::endpoint(method = get, route = "/")]
/// async fn hello() -> &'static str {
/// "Hello, World!"
/// }
///
/// // We can also use tracing/log macros directly:
/// #[shuttle_next::endpoint(method = get, route = "/goodbye")]
/// async fn goodbye() -> &'static str {
/// debug!("goodbye endpoint called");
/// "Goodbye, World!"
/// }
///
/// // We can also extract the http body in our handlers.
/// // The endpoint below takes the body from the request using the axum `BodyStream`
/// // extractor, lazily maps its bytes to uppercase and streams it back in our response:
/// #[shuttle_next::endpoint(method = post, route = "/uppercase")]
/// async fn uppercase(body: BodyStream) -> impl IntoResponse {
/// let chunk_stream = body.map_ok(|chunk| {
/// chunk
/// .iter()
/// .map(|byte| byte.to_ascii_uppercase())
/// .collect::<Vec<u8>>()
/// });
/// Response::new(StreamBody::new(chunk_stream))
/// }
/// }
/// ```
#[cfg(feature = "next")]
#[proc_macro_error]
#[proc_macro]
Expand Down
2 changes: 2 additions & 0 deletions resources/aws-rds/src/lib.rs
@@ -1,4 +1,6 @@
#![doc = include_str!("../README.md")]
//! [Shuttle AWS RDS](https://docs.shuttle.rs/resources/shuttle-aws-rds)
//! Plugin to provision databases using AWS RDS on Shuttle.

use async_trait::async_trait;
use paste::paste;
Expand Down
26 changes: 26 additions & 0 deletions resources/secrets/src/lib.rs
@@ -1,9 +1,35 @@
//! [Shuttle Secrets](https://docs.shuttle.rs/resources/shuttle-secrets)
//! A secrets plugin for Shuttle for storing environment secrets.
//!
//! # Example
//!
//! ```rust,ignore
//! #[shuttle_runtime::main]
//! async fn rocket(
//! #[shuttle_secrets::Secrets] secret_store: SecretStore,
//! ) -> ShuttleRocket {
//! // get secret defined in `Secrets.toml` file.
//! let secret = if let Some(secret) = secret_store.get("MY_API_KEY") {
//! secret
//! } else {
//! return Err(anyhow!("secret was not found").into());
//! };
//!
//! let state = MyState { secret };
//! let rocket = rocket::build().mount("/", routes![secret]).manage(state);
//!
//! Ok(rocket.into())
//! }
//!
//! ```

iulianbarbu marked this conversation as resolved.
Show resolved Hide resolved
use async_trait::async_trait;

use serde::Serialize;
pub use shuttle_service::SecretStore;
use shuttle_service::{Error, Factory, ResourceBuilder, Type};

/// A struct that represents service secrets
#[derive(Serialize)]
pub struct Secrets;

Expand Down
5 changes: 5 additions & 0 deletions resources/shared-db/src/lib.rs
@@ -1,4 +1,9 @@
#![doc = include_str!("../README.md")]
//! # [Shuttle Shared Databases](https://docs.shuttle.rs/resources/shuttle-shared-db)
//!
//! This plugin manages databases that are shared with other services on shuttle.
//! Your database will share the server with other users, but it will not
//! be accessible by other users.

#[cfg(feature = "mongodb")]
mod mongo;
Expand Down
1 change: 1 addition & 0 deletions resources/shared-db/src/postgres.rs
Expand Up @@ -4,6 +4,7 @@ use shuttle_service::{
database, error::CustomError, DbInput, DbOutput, Error, Factory, ResourceBuilder, Type,
};

/// Handles the state of a Shuttle managed Postgres DB and sets up a Postgres driver.
#[derive(Serialize)]
pub struct Postgres {
config: DbInput,
Expand Down
1 change: 1 addition & 0 deletions service/src/error.rs
Expand Up @@ -18,4 +18,5 @@ pub enum Error {
Custom(#[from] CustomError),
}

/// Type alias for an `anyhow::Error`.
pub type CustomError = anyhow::Error;
15 changes: 14 additions & 1 deletion services/shuttle-actix-web/src/lib.rs
Expand Up @@ -56,5 +56,18 @@ where
}
}

/// The return type that should be returned from the [shuttle_runtime::main] function.
/// Return type from the `[shuttle_runtime::main]` macro for an Actix-based service.
///
/// # Example
/// ```rust,no_run
/// # use shuttle_actix_web::ShuttleActixWeb;
/// # use actix_web::web::ServiceConfig;
/// #
/// #[shuttle_runtime::main]
/// async fn example_service()
/// -> ShuttleActixWeb<impl FnOnce(&mut ServiceConfig) + Send + Clone + 'static> {
/// let config = move |_cfg: &mut ServiceConfig| {};
/// Ok(config.into())
/// }
/// ```
pub type ShuttleActixWeb<F> = Result<ActixWebService<F>, shuttle_runtime::Error>;
2 changes: 2 additions & 0 deletions services/shuttle-next/src/lib.rs
@@ -1,3 +1,5 @@
//! [shuttle_next](https://docs.shuttle.rs/examples/shuttle-next)
//! A batteries-included, WASM-based backend web-framework.
pub use axum::*;
pub use futures_executor::block_on;
pub use http::Request;
Expand Down
50 changes: 49 additions & 1 deletion services/shuttle-serenity/src/lib.rs
Expand Up @@ -72,5 +72,53 @@ impl From<serenity::Client> for SerenityService {
}
}

/// The return type that should be returned from the [shuttle_runtime::main] function.
/// Return type from the `[shuttle_runtime::main]` macro for a Serenity-based service.
///
/// # Example
/// ```rust,no_run
/// # use anyhow::anyhow;
/// # use serenity::async_trait;
/// # use serenity::model::channel::Message;
/// # use serenity::model::gateway::Ready;
/// # use serenity::prelude::*;
/// # use shuttle_secrets::SecretStore;
/// # use tracing::{error, info};
/// # struct Bot;
/// # #[async_trait]
/// # impl EventHandler for Bot {
/// # async fn message(&self, ctx: Context, msg: Message) {
/// # if msg.content == "!hello" {
/// # if let Err(e) = msg.channel_id.say(&ctx.http, "world!").await {
/// # error!("Error sending message: {:?}", e);
/// # }
/// # }
/// # }
/// # async fn ready(&self, _: Context, ready: Ready) {
/// # info!("{} is connected!", ready.user.name);
/// # }
/// # }
///
/// #[shuttle_runtime::main]
/// async fn serenity(
/// #[shuttle_secrets::Secrets] secret_store: SecretStore,
/// ) -> shuttle_serenity::ShuttleSerenity {
/// // Get the discord token set in `Secrets.toml`
/// let token = if let Some(token) = secret_store.get("DISCORD_TOKEN") {
/// token
/// } else {
/// return Err(anyhow!("'DISCORD_TOKEN' was not found").into());
/// };
///
/// // Set gateway intents, which decides what events the bot will be notified about
/// let intents = GatewayIntents::GUILD_MESSAGES | GatewayIntents::MESSAGE_CONTENT;
///
/// let client = Client::builder(&token, intents)
/// .event_handler(Bot)
/// .await
/// .expect("Err creating client");
///
/// Ok(client.into())
/// }
///
/// ```
pub type ShuttleSerenity = Result<SerenityService, Error>;
16 changes: 15 additions & 1 deletion services/shuttle-tide/src/lib.rs
Expand Up @@ -36,5 +36,19 @@ impl<T> From<tide::Server<T>> for TideService<T> {
Self(router)
}
}
/// The return type that should be returned from the [shuttle_runtime::main] function.

/// Return type from the `[shuttle_runtime::main]` macro for a Tide-based service.
///
/// # Example
/// ```rust,no_run
/// use shuttle_tide::ShuttleTide;
/// #[shuttle_runtime::main]
/// async fn example_service()
/// -> ShuttleTide<()> {
/// let mut app = tide::new();
/// app.with(tide::log::LogMiddleware::new());
/// app.at("/").get(|_| async { Ok("Hello, world!") });
/// Ok(app.into())
/// }
/// ```
pub type ShuttleTide<T> = Result<TideService<T>, Error>;
33 changes: 32 additions & 1 deletion services/shuttle-tower/src/lib.rs
Expand Up @@ -83,5 +83,36 @@ where
}
}

/// The return type that should be returned from the [shuttle_runtime::main] function.
/// Shuttle service return type for the Tower framework.
/// ## Example
/// ```rust,no_run
/// # use std::convert::Infallible;
/// # use std::future::Future;
/// # use std::pin::Pin;
/// # use std::task::{Context, Poll};
/// # #[derive(Clone)]
/// # struct HelloWorld;
/// # impl tower::Service<hyper::Request<hyper::Body>> for HelloWorld {
/// # type Response = hyper::Response<hyper::Body>;
/// # type Error = Infallible;
/// # type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + Sync>>;
/// # fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
/// # Poll::Ready(Ok(()))
/// # }
/// # fn call(&mut self, _req: hyper::Request<hyper::Body>) -> Self::Future {
/// # let body = hyper::Body::from("Hello, world!");
/// # let resp = hyper::Response::builder()
/// # .status(200)
/// # .body(body)
/// # .expect("Unable to create the `hyper::Response` object");
/// # let fut = async { Ok(resp) };
/// # Box::pin(fut)
/// # }
/// # }
/// # #[shuttle_runtime::main]
/// async fn tower() -> shuttle_tower::ShuttleTower<HelloWorld> {
/// let service = HelloWorld;
/// Ok(service.into())
/// }
/// ```
pub type ShuttleTower<T> = Result<TowerService<T>, Error>;