azure_functions/
lib.rs

1//! # Azure Functions for Rust
2//!
3//! The Azure Functions for Rust crate supports creating Azure Functions with Rust.
4//!
5//! The following Azure Functions trigger bindings are supported:
6//!
7//! * [Blob trigger](bindings/struct.BlobTrigger.html)
8//! * [Cosmos DB trigger](bindings/struct.CosmosDbTrigger.html)
9//! * [Durable Activity trigger](bindings/struct.DurableOrchestrationContext.html)
10//! * [Durable Orchestration trigger](bindings/struct.DurableOrchestrationContext.html)
11//! * [Event Grid trigger](bindings/struct.EventGridEvent.html)
12//! * [Event Hub trigger](bindings/struct.EventHubTrigger.html)
13//! * [Generic trigger](bindings/struct.GenericTrigger.html)
14//! * [HTTP trigger](bindings/struct.HttpRequest.html)
15//! * [Service Bus trigger](bindings/struct.ServiceBusTrigger.html)
16//! * [Queue trigger](bindings/struct.QueueTrigger.html)
17//! * [Timer trigger](bindings/struct.TimerInfo.html)
18//!
19//! The following Azure Functions input bindings are supported:
20//!
21//! * [Blob input](bindings/struct.Blob.html)
22//! * [Cosmos DB input](bindings/struct.CosmosDbDocument.html)
23//! * [Durable orchestration client input](bindings/struct.DurableOrchestrationClient.html)
24//! * [Generic input](bindings/struct.GenericInput.html)
25//! * [SignalR connection info input](bindings/struct.SignalRConnectionInfo.html)
26//! * [Table input](bindings/struct.Table.html)
27//!
28//! The following Azure Functions output bindings are supported:
29//!
30//! * [Blob output](bindings/struct.Blob.html)
31//! * [Cosmos DB output](bindings/struct.CosmosDbDocument.html)
32//! * [Event Hub output](bindings/struct.EventHubMessage.html)
33//! * [Generic output](bindings/struct.GenericOutput.html)
34//! * [HTTP output](bindings/struct.HttpResponse.html)
35//! * [Queue output](bindings/struct.QueueMessage.html)
36//! * [SendGrid email message output](bindings/struct.SendGridMessage.html)
37//! * [Service Bus output](bindings/struct.ServiceBusMessage.html)
38//! * [SignalR group action output](bindings/struct.SignalRGroupAction.html)
39//! * [SignalR message output](bindings/struct.SignalRMessage.html)
40//! * [Table output](bindings/struct.Table.html)
41//! * [Twilio SMS message output](bindings/struct.TwilioSmsMessage.html)
42//!
43//! Eventually more bindings will be implemented, including custom binding data.
44//!
45//! # Example
46//!
47//! Start by installing the Azure Functions for Rust SDK:
48//!
49//! ```bash
50//! $ cargo install azure-functions-sdk
51//! ```
52//!
53//! Create a new Azure Functions for Rust application:
54//!
55//! ```bash
56//! $ cargo func new-app hello && cd hello
57//! ```
58//!
59//! Create a HTTP-triggered function:
60//!
61//! ```bash
62//! $ cargo func new http -n hello
63//! ```
64//!
65//! This generates `src/functions/hello.rs` with the following contents:
66//!
67//! ```rust,ignore
68//! use azure_functions::{
69//!     bindings::{HttpRequest, HttpResponse},
70//!     func,
71//! };
72//!
73//! #[func]
74//! pub fn hello(req: HttpRequest) -> HttpResponse {
75//!     "Hello from Rust!".into()
76//! }
77//! ```
78//!
79//! Azure Functions are implemented by applying a `#[func]` attribute to a Rust function.
80//!
81//! Run the application with `cargo func run`:
82//!
83//! ```bash
84//! $ cargo func run
85//! ```
86//!
87//! The above Azure Function can be invoked with `http://localhost:8080/api/hello`.
88//!
89//! The expected response would be `Hello from Rust!`.
90#![deny(unused_extern_crates)]
91#![deny(missing_docs)]
92#![cfg_attr(test, recursion_limit = "128")]
93
94#[doc(no_inline)]
95pub use azure_functions_codegen::export;
96#[doc(no_inline)]
97pub use azure_functions_codegen::func;
98
99#[doc(hidden)]
100pub use azure_functions_shared::codegen;
101
102mod backtrace;
103mod commands;
104mod logger;
105mod registry;
106mod util;
107mod worker;
108
109pub mod bindings;
110pub mod blob;
111pub mod context;
112pub mod durable;
113pub mod event_hub;
114pub mod generic;
115pub mod http;
116pub mod send_grid;
117pub mod signalr;
118pub mod timer;
119#[doc(no_inline)]
120pub use azure_functions_shared::rpc;
121
122use crate::commands::{Init, Run, SyncExtensions};
123use crate::registry::Registry;
124use clap::{App, AppSettings};
125
126#[doc(hidden)]
127pub trait IntoVec<T> {
128    fn into_vec(self) -> Vec<T>;
129}
130
131#[doc(hidden)]
132pub trait FromVec<T> {
133    fn from_vec(vec: Vec<T>) -> Self;
134}
135
136/// The main entry point for the Azure Functions for Rust worker.
137///
138/// This entry point does not use any additional Azure Functions binding extensions.
139///
140/// # Examples
141///
142/// ```rust,ignore
143/// mod example;
144///
145/// azure_functions::export! {
146///     example::function,
147/// }
148///
149/// fn main() {
150///     azure_functions::worker_main(::std::env::args(), EXPORTS);
151/// }
152/// ```
153pub fn worker_main(args: impl Iterator<Item = String>, functions: &[&'static codegen::Function]) {
154    worker_main_with_extensions(args, functions, &[])
155}
156
157/// The main entry point for the Azure Functions for Rust worker.
158///
159/// This entry point uses additional Azure Function binding extensions.
160///
161/// # Examples
162///
163/// ```rust,ignore
164/// fn main() {
165///     azure_functions::worker_main_with_extensions(
166///         ::std::env::args(),
167///         functions::EXPORTS,
168///         &[("Microsoft.Azure.WebJobs.Extensions.Kafka", "1.0.0-alpha")]
169///     );
170/// }
171/// ```
172pub fn worker_main_with_extensions(
173    args: impl Iterator<Item = String>,
174    functions: &[&'static codegen::Function],
175    extensions: &[(&str, &str)],
176) {
177    let registry = Registry::new(functions);
178
179    let app = App::new("Azure Functions for Rust worker")
180        .version(env!("CARGO_PKG_VERSION"))
181        .about("Implements the Azure Functions for Rust worker.")
182        .setting(AppSettings::SubcommandRequiredElseHelp)
183        .setting(AppSettings::VersionlessSubcommands)
184        .subcommand(Init::create_subcommand())
185        .subcommand(SyncExtensions::create_subcommand())
186        .subcommand(Run::create_subcommand());
187
188    if let Err(e) = match app.get_matches_from(args).subcommand() {
189        ("init", Some(args)) => Init::from(args).execute(registry, extensions),
190        ("sync-extensions", Some(args)) => SyncExtensions::from(args).execute(registry, extensions),
191        ("run", Some(args)) => Run::from(args).execute(registry),
192        _ => panic!("expected a subcommand."),
193    } {
194        eprintln!("error: {}", e);
195        std::process::exit(1);
196    }
197}