### Hello World Example Source: https://docs.rs/poem-openapi/latest/poem_openapi/index.html A basic example demonstrating how to set up a simple API with Poem and poem-openapi, including a root endpoint that returns 'Hello World'. ```APIDOC ## GET / ### Description Returns a simple "Hello World" message. ### Method GET ### Endpoint / ### Parameters None ### Request Body None ### Request Example None ### Response #### Success Response (200) - **body** (PlainText) - The "Hello World" message. ### Response Example ``` Hello World ``` ``` -------------------------------- ### Rust Example: Uploading and Streaming Binary Data Source: https://docs.rs/poem-openapi/latest/src/poem_openapi/payload/binary.rs.html Demonstrates how to define API endpoints for uploading binary data as `Binary>` and streaming it as `Binary`. Includes setup with `poem_openapi` and `TestClient` for testing. ```rust use poem::{ Body, IntoEndpoint, Request, Result, error::BadRequest, http::{Method, StatusCode, Uri}, test::TestClient, }; use poem_openapi::{ OpenApi, OpenApiService, payload::{Binary, Json}, }; use tokio::io::AsyncReadExt; struct MyApi; #[OpenApi] impl MyApi { #[oai(path = "/upload", method = "post")] async fn upload_binary(&self, data: Binary>) -> Json { Json(data.len()) } #[oai(path = "/upload_stream", method = "post")] async fn upload_binary_stream(&self, data: Binary) -> Result> { let mut reader = data.0.into_async_read(); let mut bytes = Vec::new(); reader.read_to_end(&mut bytes).await.map_err(BadRequest)?; Ok(Json(bytes.len())) } } let api = OpenApiService::new(MyApi, "Demo", "0.1.0"); let cli = TestClient::new(api); # tokio::runtime::Runtime::new().unwrap().block_on(async { let resp = cli .post("/upload") .content_type("application/octet-stream") .body("abcdef") .send() .await; resp.assert_status_is_ok(); resp.assert_text("6").await; let resp = cli .post("/upload_stream") .content_type("application/octet-stream") .body("abcdef") .send() .await; resp.assert_status_is_ok(); resp.assert_text("6").await; # }); ``` -------------------------------- ### Example Usage Source: https://docs.rs/poem-openapi/latest/poem_openapi/attr.Webhook.html Example of how to define and use a webhook with poem-openapi. ```APIDOC ## Examples ```rust use poem_openapi::{Object, Webhook, payload::Json, OpenApiService}; #[derive(Object)] struct Pet { id: i64, name: String, } #[Webhook] trait MyWebhooks { /// This is the summary of the operation /// /// This is the description of the operation #[oai(method = "post")] fn new_pet(&self, pet: Json); } let api = OpenApiService::new((), "Demo", "1.0.0") .webhooks::<&dyn MyWebhooks>(); ``` ``` -------------------------------- ### Hello World Example Source: https://docs.rs/poem-openapi/latest/index.html A basic example demonstrating how to set up a simple "Hello World" API using poem-openapi. This includes defining an API structure, implementing an endpoint, and serving the API with Swagger UI. ```APIDOC ## GET / ### Description Responds with a simple "Hello World" message. ### Method GET ### Endpoint / ### Request Body None ### Response #### Success Response (200) - **body** (PlainText<&'static str>) - The "Hello World" message. ### Request Example None ### Response Example ``` Hello World ``` ``` -------------------------------- ### Base64 Payload Usage Example Source: https://docs.rs/poem-openapi/latest/src/poem_openapi/payload/base64_payload.rs.html Demonstrates how to use `Base64` for uploading and downloading binary data in a Poem OpenAPI service. It shows receiving base64 encoded data in a POST request and returning base64 encoded data in a GET response. ```APIDOC ## POST /upload ### Description Uploads binary data encoded in Base64. ### Method POST ### Endpoint /upload ### Parameters #### Request Body - **data** (Base64>) - Required - The binary data encoded as a Base64 string. ### Request Example ```http POST /upload HTTP/1.1 Content-Type: text/plain YWJjZGVm ``` ### Response #### Success Response (200) - **body** (Json) - The length of the uploaded binary data. #### Response Example ```http HTTP/1.1 200 OK Content-Type: application/json 6 ``` ## GET /download ### Description Downloads binary data encoded in Base64. ### Method GET ### Endpoint /download ### Response #### Success Response (200) - **body** (Base64>) - The binary data encoded as a Base64 string. #### Response Example ```http HTTP/1.1 200 OK Content-Type: text/plain; charset=utf-8 YWJjZGVm ``` ``` -------------------------------- ### Example of capacity() Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/struct.Email.html Returns this String’s capacity in bytes. Useful for understanding memory allocation. ```rust let s = String::with_capacity(10); assert!(s.capacity() >= 10); ``` -------------------------------- ### Upload Binary Data Example Source: https://docs.rs/poem-openapi/latest/poem_openapi/payload/struct.Binary.html Demonstrates uploading binary data as Vec using the Binary payload and testing the response. ```rust use poem::{ Body, IntoEndpoint, Request, Result, error::BadRequest, http::{Method, StatusCode, Uri}, test::TestClient, }; use poem_openapi::* use poem_openapi::payload::{Binary, Json}; use tokio::io::AsyncReadExt; struct MyApi; #[OpenApi] impl MyApi { #[oai(path = "/upload", method = "post")] async fn upload_binary(&self, data: Binary>) -> Json { Json(data.len()) } #[oai(path = "/upload_stream", method = "post")] async fn upload_binary_stream(&self, data: Binary) -> Result> { let mut reader = data.0.into_async_read(); let mut bytes = Vec::new(); reader.read_to_end(&mut bytes).await.map_err(BadRequest)?; Ok(Json(bytes.len())) } } let api = OpenApiService::new(MyApi, "Demo", "0.1.0"); let cli = TestClient::new(api); let resp = cli .post("/upload") .content_type("application/octet-stream") .body("abcdef") .send() .await; resp.assert_status_is_ok(); resp.assert_text("6").await; let resp = cli .post("/upload_stream") .content_type("application/octet-stream") .body("abcdef") .send() .await; resp.assert_status_is_ok(); resp.assert_text("6").await; ``` -------------------------------- ### Example Usage of #[OpenApi] with prefix_path and tag Source: https://docs.rs/poem-openapi/latest/poem_openapi/attr.OpenApi.html Demonstrates how to use the `#[OpenApi]` attribute with `prefix_path` and `tag` to define an API endpoint. ```APIDOC ### §Example ```rust use poem_openapi::{OpenApi, Tags}; use poem_openapi::param::Path; use poem_openapi::payload::PlainText; #[derive(Tags)] enum MyTags { V1 } struct Api; #[OpenApi(prefix_path = "/v1/:customer_id", tag = "MyTags::V1")] impl Api { /// Greet the customer /// /// # Example /// /// Call `/v1/1234/hello` to get the response `"Hello 1234!"`. #[oai(path = "/hello", method = "get")] async fn hello(&self, customer_id: Path) -> PlainText { PlainText(format!("Hello {}!", customer_id.0)) } } ``` ``` -------------------------------- ### Define the Example Trait Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/trait.Example.html This trait defines a required method `example()` that must be implemented by types that represent an example. It is not dyn compatible. ```rust pub trait Example { // Required method fn example() -> Self; } ``` -------------------------------- ### Multiple Authentication Methods Example Source: https://docs.rs/poem-openapi/latest/poem_openapi/derive.SecurityScheme.html Illustrates how to define multiple authentication methods using an enum with the `SecurityScheme` derive macro. ```APIDOC ## Multiple Authentication Methods When `SecurityScheme` macro is used with an enumerated type, it is used to define multiple authentication methods. ```rust use poem_openapi::{OpenApi, SecurityScheme}; use poem_openapi::payload::PlainText; use poem_openapi::auth::{ApiKey, Basic}; #[derive(SecurityScheme)] #[oai(ty = "basic")] struct MySecurityScheme1(Basic); #[derive(SecurityScheme)] #[oai(ty = "api_key", key_name = "X-API-Key", key_in = "header")] struct MySecurityScheme2(ApiKey); #[derive(SecurityScheme)] enum MySecurityScheme { MySecurityScheme1(MySecurityScheme1), MySecurityScheme2(MySecurityScheme2), } struct MyApi; #[OpenApi] impl MyApi { #[oai(path = "/test", method = "get")] async fn test(&self, auth: MySecurityScheme) -> PlainText { match auth { MySecurityScheme::MySecurityScheme1(auth) => { PlainText(format!("basic: {}", auth.0.username)) } MySecurityScheme::MySecurityScheme2(auth) => { PlainText(format!("api-key: {}", auth.0.key)) } } } } ``` ``` -------------------------------- ### Example of ResponseContent Enum Usage Source: https://docs.rs/poem-openapi/latest/poem_openapi/derive.ResponseContent.html This example demonstrates how to use the `ResponseContent` derive macro with an enum that includes different payload types like Json, PlainText, and Binary. It also shows how to integrate this with `ApiResponse`. ```rust use poem_openapi::{ payload::{Binary, Json, PlainText}, ApiResponse, ResponseContent, }; #[derive(ResponseContent)] enum MyResponseContent { A(Json), B(PlainText), C(Binary>), } #[derive(ApiResponse)] enum MyResponse { #[oai(status = 200)] Ok(MyResponseContent), } ``` -------------------------------- ### Example: Creating and Configuring an EventStream Source: https://docs.rs/poem-openapi/latest/poem_openapi/payload/struct.EventStream.html Demonstrates how to create an EventStream from an iterator, convert its items into JSON strings, and format them as SSE events with a specific event type. ```rust use poem::web::sse::Event; use poem_openapi::{Object, payload::EventStream, types::ToJSON}; #[derive(Debug, Object)] struct MyEvent { value: i32, } EventStream::new(futures_util::stream::iter(vec![ MyEvent { value: 1 }, MyEvent { value: 2 }, MyEvent { value: 3 }, ])) .to_event(|event| { let json = event.to_json_string(); Event::message(json).event_type("push") }); ``` -------------------------------- ### Example Usage of #[OpenApi] with operation-level tag Source: https://docs.rs/poem-openapi/latest/poem_openapi/attr.OpenApi.html Illustrates using the `#[OpenApi]` attribute with an operation-level `tag` parameter. ```APIDOC ### §Example ```rust use poem_openapi::{OpenApi, Tags}; use poem_openapi::param::Path; use poem_openapi::payload::PlainText; #[derive(Tags)] enum MyTags { V1 } struct Api; #[OpenApi] impl Api { /// Greet the customer /// /// # Example /// /// Call `/v1/1234/hello` to get the response `"Hello 1234!"`. #[oai(path = "/v1/:customer_id/hello", method = "get", tag = "MyTags::V1")] async fn hello(&self, customer_id: Path) -> PlainText { PlainText(format!("Hello {}!", customer_id.0)) } } ``` ``` -------------------------------- ### Example of push_str() Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/struct.Email.html Appends a given string slice onto the end of this String. Available on non-`no_global_oom_handling` only. Panics if the new capacity exceeds `isize::MAX` bytes. ```rust let mut s = String::from("foo"); s.push_str("bar"); assert_eq!("foobar", s); ``` -------------------------------- ### LicenseObject::new Source: https://docs.rs/poem-openapi/latest/poem_openapi/struct.LicenseObject.html Creates a new LicenseObject with the given name. This is the starting point for defining license information. ```APIDOC ## LicenseObject::new ### Description Creates a license object by name. ### Signature ```rust pub fn new(name: impl Into) -> LicenseObject ``` ### Parameters * `name` (impl Into) - The name of the license. ``` -------------------------------- ### Example of reserve() Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/struct.Email.html Reserves capacity for at least additional bytes more than the current length. Available on non-`no_global_oom_handling` only. Panics if the new capacity exceeds `isize::MAX` bytes. ```rust let mut s = String::new(); s.reserve(10); assert!(s.capacity() >= 10); ``` ```rust let mut s = String::with_capacity(10); s.push('a'); s.push('b'); let capacity = s.capacity(); assert_eq!(2, s.len()); assert!(capacity >= 10); s.reserve(8); assert_eq!(capacity, s.capacity()); ``` -------------------------------- ### Response Constructor Source: https://docs.rs/poem-openapi/latest/src/poem_openapi/payload/response.rs.html Provides a constructor for the `Response` struct, initializing it with a given payload. This is the starting point for creating a new response object. ```rust impl Response { /// Create a response object. #[must_use] pub fn new(resp: T) -> Self { Self { inner: resp, status: None, headers: HeaderMap::new(), } } ``` -------------------------------- ### Experimental: Get substring range indices Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/struct.Email.html This is a nightly-only experimental API. It splits a string by a pattern and returns an iterator yielding the start and end byte indices of each matched substring within the original string. ```rust #![feature(substr_range)] let data = "a, b, b, a"; let mut iter = data.split(", ").map(|s| data.substr_range(s).unwrap()); assert_eq!(iter.next(), Some(0..1)); assert_eq!(iter.next(), Some(3..4)); assert_eq!(iter.next(), Some(6..7)); assert_eq!(iter.next(), Some(9..10)); ``` -------------------------------- ### Normalize Path String Source: https://docs.rs/poem-openapi/latest/src/poem_openapi/path_util.rs.html Ensures a path string starts with a '/' and handles empty paths by returning '/'. Useful for standardizing path inputs. ```rust fn normalize_path(path: &str) -> String { if path.is_empty() { "/".to_string() } else if !path.starts_with('/') { format!("/{path}") } else { path.to_string() } } ``` -------------------------------- ### Basic Hello World API with Poem OpenAPI Source: https://docs.rs/poem-openapi/latest/src/poem_openapi/lib.rs.html This example demonstrates a simple "Hello World" API using Poem and poem-openapi. It defines a basic API structure, an index endpoint, and sets up the server with Swagger UI integration. ```rust use poem::{listener::TcpListener, Route, Server}; use poem_openapi::{payload::PlainText, OpenApi, OpenApiService}; struct Api; #[OpenApi] impl Api { /// Hello world #[oai(path = "/", method = "get")] async fn index(&self) -> PlainText<&'static str> { PlainText("Hello World") } } #[tokio::main] async fn main() { let api_service = OpenApiService::new(Api, "Hello World", "1.0").server("http://localhost:3000"); let ui = api_service.swagger_ui(); let app = Route::new().nest("/", api_service).nest("/docs", ui); Server::new(TcpListener::bind("127.0.0.1:3000")) .run(app) .await; } ``` -------------------------------- ### Example of reserve_exact() Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/struct.Email.html Reserves the minimum capacity for at least additional bytes more than the current length. Available on non-`no_global_oom_handling` only. Panics if the new capacity exceeds `isize::MAX` bytes. ```rust let mut s = String::new(); s.reserve_exact(10); assert!(s.capacity() >= 10); ``` ```rust let mut s = String::with_capacity(10); s.push('a'); s.push('b'); let capacity = s.capacity(); assert_eq!(2, s.len()); assert!(capacity >= 10); s.reserve_exact(8); assert_eq!(capacity, s.capacity()); ``` -------------------------------- ### Example Trait Definition Source: https://docs.rs/poem-openapi/latest/src/poem_openapi/types/mod.rs.html Defines a generic `Example` trait with a single method `example()` that returns an instance of the implementing type. This is likely used for providing example data. ```rust pub trait Example { /// Returns the example object fn example() -> Self; } ``` -------------------------------- ### Initialize Registry Source: https://docs.rs/poem-openapi/latest/src/poem_openapi/registry/mod.rs.html Creates a new, empty Registry instance. ```rust pub fn new() -> Self { Default::default() } ``` -------------------------------- ### Basic API Implementation Source: https://docs.rs/poem-openapi/latest/src/poem_openapi/lib.rs.html Demonstrates a simple 'Hello World' API endpoint using Poem and poem-openapi. This includes setting up the API structure, defining an endpoint with OpenAPI attributes, and running the server. ```APIDOC ## GET / ### Description Provides a simple "Hello World" response. ### Method GET ### Endpoint / ### Request Body None ### Response #### Success Response (200) - **body** (PlainText<&'static str>) - The "Hello World" message. ### Request Example None ### Response Example ```text Hello World ``` ``` -------------------------------- ### Rust nightly substr_range example Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/struct.Hostname.html This example demonstrates the usage of the `substr_range` method, which is a nightly-only experimental API. It returns the byte range of a substring within the original string. ```rust #![feature(substr_range)] let data = "a, b, b, a"; let mut iter = data.split(", ").map(|s| data.substr_range(s).unwrap()); assert_eq!(iter.next(), Some(0..1)); assert_eq!(iter.next(), Some(3..4)); assert_eq!(iter.next(), Some(6..7)); assert_eq!(iter.next(), Some(9..10)); ``` -------------------------------- ### Example of try_reserve() Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/struct.Email.html Tries to reserve capacity for at least additional bytes more than the current length. Returns a Result indicating success or failure due to capacity overflow or allocation errors. ```rust let mut s = String::with_capacity(10); // Example of successful reservation (assuming enough memory) let result = s.try_reserve(5); assert!(result.is_ok()); assert!(s.capacity() >= 15); // Example that might fail if capacity overflows (highly unlikely in practice for small values) // let large_additional: usize = usize::MAX / 2; // let fail_result = s.try_reserve(large_additional); // assert!(fail_result.is_err()); ``` -------------------------------- ### Example Union without Discriminator Source: https://docs.rs/poem-openapi/latest/poem_openapi/derive.Union.html Defines a union type `MyObj` with three variants: `A` (a struct), `B` (a boolean), and `C` (a string). This example demonstrates a union where an explicit discriminator is not specified. ```rust use poem_openapi::{Object, Union}; #[derive(Object, Debug, PartialEq)] struct A { v1: i32, v2: String, } #[derive(Union, Debug, PartialEq)] enum MyObj { A(A), B(bool), C(String), } ``` -------------------------------- ### Get Mutable Raw Pointer to String Slice Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/struct.Hostname.html Use `as_mut_ptr` to get a mutable raw pointer to the first byte of a string slice. Modifications must maintain UTF-8 validity. ```rust let mut s = String::from("hello"); let ptr = s.as_mut_ptr(); // Note: The actual modification would happen here using the pointer. ``` -------------------------------- ### Create a Server Object Source: https://docs.rs/poem-openapi/latest/src/poem_openapi/openapi.rs.html Use `ServerObject::new` to create a server object with a URL. Chain methods like `description` and `variable` to configure it further. ```rust impl> From for ServerObject { fn from(url: T) -> Self { Self::new(url) } } impl ServerObject { /// Create a server object by url. pub fn new(url: impl Into) -> ServerObject { Self { url: url.into(), description: None, variables: BTreeMap::new(), } } /// Sets an string describing the host designated by the URL. #[must_use] pub fn description(self, description: impl Into) -> Self { Self { description: Some(description.into()), ..self } } /// Adds a server variable with a limited set of values. /// /// The variable name must be present in the server URL in curly braces. #[must_use] pub fn enum_variable( mut self, name: impl Into, description: impl Into, default: impl Into, enum_values: Vec>, ) -> Self { self.variables.insert( name.into(), MetaServerVariable { description: description.into(), default: default.into(), enum_values: enum_values.into_iter().map(Into::into).collect(), }, ); self } /// Adds a server variable that can take any value. /// /// The variable name must be present in the server URL in curly braces. #[must_use] pub fn variable( mut self, name: impl Into, description: impl Into, default: impl Into, ) -> Self { self.variables.insert( name.into(), MetaServerVariable { description: description.into(), default: default.into(), enum_values: Vec::new(), }, ); self } } ``` -------------------------------- ### OpenApiService::new Source: https://docs.rs/poem-openapi/latest/poem_openapi/struct.OpenApiService.html Creates a new OpenApiService instance, initializing the OpenAPI container with the provided API, title, and version. ```APIDOC ## OpenApiService::new ### Description Create an OpenAPI container. ### Signature ```rust pub fn new(api: T, title: impl Into, version: impl Into) -> Self ``` ``` -------------------------------- ### Safely Get String Subslice Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/struct.Email.html The `get` method returns an `Option<&str>` representing a subslice. It returns `None` if the indices are out of bounds or do not fall on UTF-8 character boundaries, preventing panics. ```rust let v = String::from("🗻∈🌏"); assert_eq!(Some("🗻"), v.get(0..4)); // indices not on UTF-8 sequence boundaries assert!(v.get(1..).is_none()); assert!(v.get(..8).is_none()); // out of bounds assert!(v.get(..42).is_none()); ``` -------------------------------- ### Safely get Err value with into_err Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/type.ParseResult.html Use `into_err` to get the contained `Err` value. This method is guaranteed not to panic and serves as a compile-time safeguard against changes that might introduce panics. ```rust fn only_bad_news() -> Result { Err("Oops, it failed".into()) } let error: String = only_bad_news().into_err(); println!("{error}"); ``` -------------------------------- ### Safely get Ok value with into_ok Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/type.ParseResult.html Use `into_ok` to get the contained `Ok` value. This method is guaranteed not to panic and can be used as a compile-time safeguard against future changes that might introduce panics. ```rust fn only_good_news() -> Result { Ok("this is fine".into()) } let s: String = only_good_news().into_ok(); println!("{s}"); ``` -------------------------------- ### sample Source: https://docs.rs/poem-openapi/latest/poem_openapi/payload/struct.Binary.html Sample a new value, using the given distribution. ```APIDOC ## fn sample(&mut self, distr: D) -> T ### Description Sample a new value, using the given distribution. ### Type Parameters - `T`: The type of the value to sample. - `D`: The type of the distribution, which must implement `Distribution`. ### Parameters - `distr`: The distribution to use for sampling. ``` -------------------------------- ### Product Implementation for Result Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/type.ParseResult.html Demonstrates how to use the `product` method on an iterator of Results. It calculates the product of successful values, short-circuiting and returning the first error encountered. ```rust let nums = vec!["5", "10", "1", "2"]; let total: Result = nums.iter().map(|w| w.parse::()).product(); assert_eq!(total, Ok(100)); ``` ```rust let nums = vec!["5", "10", "one", "2"]; let total: Result = nums.iter().map(|w| w.parse::()).product(); assert!(total.is_err()); ``` -------------------------------- ### get Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/struct.Password.html Returns a subslice of `str` without panicking. ```APIDOC ## get ### Description Returns a subslice of `str`. This is the non-panicking alternative to indexing the `str`. Returns `None` whenever equivalent indexing operation would panic. ### Method `get(&self, i: I) -> Option<&>::Output> where I: SliceIndex` ### Examples ```rust let v = String::from("🗻∈🌏"); assert_eq!(Some("🗻"), v.get(0..4)); // indices not on UTF-8 sequence boundaries assert!(v.get(1..).is_none()); assert!(v.get(..8).is_none()); // out of bounds assert!(v.get(..42).is_none()); ``` ``` -------------------------------- ### OpenApiService::new Source: https://docs.rs/poem-openapi/latest/src/poem_openapi/openapi.rs.html Creates a new OpenApiService instance with the provided API implementation, title, and version. ```APIDOC ## OpenApiService::new ### Description Creates a new OpenAPI container with the given API implementation, title, and version. ### Signature ```rust pub fn new(api: T, title: impl Into, version: impl Into) -> Self ``` ### Parameters - `api`: The API implementation. - `title`: The title of the API. - `version`: The version of the API. ``` -------------------------------- ### Get Upload Size Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/multipart/struct.Upload.html Returns the size of the uploaded file in bytes. ```rust pub fn size(&self) -> usize ``` -------------------------------- ### Any Trait Implementation for T Source: https://docs.rs/poem-openapi/latest/poem_openapi/auth/struct.Bearer.html Provides a method to get the TypeId of a type, part of the Any trait. ```rust fn type_id(&self) -> TypeId ``` -------------------------------- ### Attachment Creation and Configuration Source: https://docs.rs/poem-openapi/latest/src/poem_openapi/payload/attachment.rs.html Provides methods to create and configure an `Attachment`. Use `new` to create with data, `attachment_type` to set display behavior, and `filename` to specify the downloaded file's name. ```rust /// Create an attachment with data. pub fn new(data: T) -> Self { Self { data: Binary(data), ty: AttachmentType::Attachment, filename: None, } } /// Specify the attachment. (defaults to: [`AttachmentType::Inline`]) #[must_use] pub fn attachment_type(self, ty: AttachmentType) -> Self { Self { ty, ..self } } /// Specify the file name. #[must_use] pub fn filename(self, filename: impl Into) -> Self { Self { filename: Some(filename.into()), ..self } } ``` -------------------------------- ### Example Usage of MaybeUndefined in API Endpoint Source: https://docs.rs/poem-openapi/latest/src/poem_openapi/types/maybe_undefined.rs.html Demonstrates how to use MaybeUndefined in an API endpoint to handle updates to a resource. It shows how to match on the different states of MaybeUndefined (Undefined, Null, Value) to update the resource's attributes accordingly. This example requires setting up a basic API service with Poem and Poem OpenAPI. ```rust use std::{borrow::Cow, ops::Deref}; use poem::{http::HeaderValue, web::Field as PoemField}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value; use crate::{ registry::{MetaSchemaRef, Registry}, types::{ ParseError, ParseFromJSON, ParseFromMultipartField, ParseFromParameter, ParseResult, ToHeader, ToJSON, Type, }, }; /// Similar to `Option`, but it has three states, `undefined`, `null` and `x`. /// /// # Example /// /// ``` /// use poem::{test::TestClient, IntoEndpoint}; /// use poem_openapi::{payload::Json, types::MaybeUndefined, Object, OpenApi, OpenApiService}; /// use tokio::sync::Mutex; /// use serde_json::json; /// /// #[derive(Object, Clone, Default)] /// struct Resource { /// attr1: Option, /// attr2: Option, /// } /// /// #[derive(Object)] /// struct UpdateResourceRequest { /// attr1: MaybeUndefined, /// attr2: MaybeUndefined, /// } /// /// struct Api { /// resource: Mutex, /// } /// /// #[OpenApi] /// impl Api { /// #[oai(path = "/get", method = "get")] /// async fn get_resource(&self) -> Json { /// Json(self.resource.lock().await.clone()) /// } /// /// #[oai(path = "/put", method = "put")] /// async fn update_resource(&self, req: Json) { /// let mut resource = self.resource.lock().await; /// /// match req.0.attr1 { /// MaybeUndefined::Null => resource.attr1 = None, /// MaybeUndefined::Value(value) => resource.attr1 = Some(value), /// MaybeUndefined::Undefined => {} // No change if undefined /// } /// /// match req.0.attr2 { /// MaybeUndefined::Null => resource.attr2 = None, /// MaybeUndefined::Value(value) => resource.attr2 = Some(value), /// MaybeUndefined::Undefined => {} // No change if undefined /// } /// } /// } /// /// let api_service = OpenApiService::new( /// Api { /// resource: Default::default(), /// }, /// "Test", /// "1.0", /// ); /// /// let cli = TestClient::new(api_service.into_endpoint()); /// /// # tokio::runtime::Runtime::new().unwrap().block_on(async { /// cli.get("/get").send().await.assert_json(json!({{"attr1": null, "attr2": null}})); /// /// cli.put("/put").body_json(&json!({{"attr1": 100i32}})).send().await.assert_status_is_ok(); /// cli.get("/get").send().await.assert_json(json!({{"attr1": 100i32, "attr2": null}})); /// /// cli.put("/put").body_json(&json!({{"attr1": null, "attr2": "abc"}})).send().await.assert_status_is_ok(); /// cli.get("/get").send().await.assert_json(json!({{"attr1": null, "attr2": "abc"}})); /// # }); /// ``` #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] pub enum MaybeUndefined { /// Undefined Undefined, /// Null Null, /// Value Value(T), } impl Default for MaybeUndefined { fn default() -> Self { Self::Undefined } } impl From for MaybeUndefined { fn from(value: T) -> Self { MaybeUndefined::Value(value) } } impl IntoIterator for MaybeUndefined { type Item = T; type IntoIter = std::option::IntoIter; fn into_iter(self) -> Self::IntoIter { self.take().into_iter() } } impl MaybeUndefined { /// Create a `MaybeUndefined` from `Option`, returns /// `MaybeUndefined::Undefined` if this value is none. pub fn from_opt_undefined(value: Option) -> Self { match value { Some(value) => MaybeUndefined::Value(value), None => MaybeUndefined::Undefined, } } /// Create a `MaybeUndefined` from `Option`, returns /// `MaybeUndefined::Null` if this value is none. pub fn from_opt_null(value: Option) -> Self { match value { Some(value) => MaybeUndefined::Value(value), None => MaybeUndefined::Null, } } /// Returns true if the `MaybeUndefined` is undefined. #[inline] pub const fn is_undefined(&self) -> bool { matches!(self, MaybeUndefined::Undefined) } /// Returns true if the `MaybeUndefined` is null. #[inline] pub const fn is_null(&self) -> bool { matches!(self, MaybeUndefined::Null) } /// Returns true if the `MaybeUndefined` contains value. #[inline] pub const fn is_value(&self) -> bool { matches!(self, MaybeUndefined::Value(_)) } /// Returns `None` if the the `MaybeUndefined` is /// `undefined` or `null`, otherwise returns `Some(&T)`. ``` -------------------------------- ### Create a Contact Object Source: https://docs.rs/poem-openapi/latest/src/poem_openapi/openapi.rs.html Use `ContactObject::new` to initialize a contact object. Configure name, URL, and email using dedicated methods. ```rust impl ContactObject { /// Create a new Contact object #[inline] pub fn new() -> Self { Self::default() } /// Sets the identifying name of the contact person/organization. #[must_use] pub fn name(self, name: impl Into) -> Self { Self { name: Some(name.into()), ..self } } /// Sets the URL pointing to the contact information. #[must_use] pub fn url(self, url: impl Into) -> Self { Self { url: Some(url.into()), ..self } } /// Sets the email address of the contact person/organization. #[must_use] pub fn email(self, email: impl Into) -> Self { Self { email: Some(email.into()), ..self } } } ``` -------------------------------- ### get Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/struct.Hostname.html Safely retrieves a subslice of the string, returning `None` if the indices are invalid or out of bounds. ```APIDOC ## get ### Description Returns a subslice of `str`. This is the non-panicking alternative to indexing the `str`. Returns `None` whenever equivalent indexing operation would panic. ### Method `fn get(&self, i: I) -> Option<&>::Output>` where I: SliceIndex ### Parameters #### Path Parameters - **i** (I) - The range or index to slice the string with. ### Response #### Success Response (Option<&>::Output>) - Returns `Some` containing the subslice if the indices are valid, otherwise `None`. ### Request Example ```rust let v = String::from("🗻∈🌏"); assert_eq!(Some("🗻"), v.get(0..4)); // indices not on UTF-8 sequence boundaries assert!(v.get(1..).is_none()); assert!(v.get(..8).is_none()); // out of bounds assert!(v.get(..42).is_none()); ``` ``` -------------------------------- ### Create a License Object Source: https://docs.rs/poem-openapi/latest/src/poem_openapi/openapi.rs.html Create a `LicenseObject` using `LicenseObject::new` with a name. Optionally set an identifier or URL. ```rust impl> From for LicenseObject { fn from(url: T) -> Self { Self::new(url) } } impl LicenseObject { /// Create a license object by name. pub fn new(name: impl Into) -> LicenseObject { Self { name: name.into(), identifier: None, url: None, } } /// Sets the [`SPDX`](https://spdx.org/spdx-specification-21-web-version#h.jxpfx0ykyb60) license expression for the API. #[must_use] pub fn identifier(self, identifier: impl Into) -> Self { Self { identifier: Some(identifier.into()), ..self } } } ``` -------------------------------- ### Get Optional Value from MaybeUndefined Source: https://docs.rs/poem-openapi/latest/src/poem_openapi/types/maybe_undefined.rs.html Returns `Some(&T)` if the `MaybeUndefined` is `Value(T)`, otherwise returns `None`. ```rust pub const fn value(&self) -> Option<&T> { match self { MaybeUndefined::Value(value) => Some(value), _ => None, } } ``` -------------------------------- ### OpenApiService::redoc_html Source: https://docs.rs/poem-openapi/latest/poem_openapi/struct.OpenApiService.html Creates the Redoc HTML. Available only on `crate feature`redoc`. ```APIDOC ## OpenApiService::redoc_html ### Description Create the Redoc HTML ### Availability Available on **crate feature`redoc`** only. ### Signature ```rust pub fn redoc_html(&self) -> String where T: OpenApi, W: Webhook ``` ``` -------------------------------- ### Get Upload File Name Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/multipart/struct.Upload.html Retrieves the file name from the Content-Disposition header of the upload. ```rust pub fn file_name(&self) -> Option<&str> ``` -------------------------------- ### Create ServerObject with URL Source: https://docs.rs/poem-openapi/latest/poem_openapi/struct.ServerObject.html Use this function to create a new ServerObject instance, providing the server's URL. ```rust pub fn new(url: impl Into) -> ServerObject ``` -------------------------------- ### Set Server Description Source: https://docs.rs/poem-openapi/latest/poem_openapi/struct.ServerObject.html Add a descriptive string to the ServerObject to explain the host designated by the URL. ```rust pub fn description(self, description: impl Into) -> Self ``` -------------------------------- ### Get Upload Content Type Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/multipart/struct.Upload.html Retrieves the content type of the uploaded file, if available. ```rust pub fn content_type(&self) -> Option<&str> ``` -------------------------------- ### Create OpenAPI Explorer Endpoint (with openapi-explorer feature) Source: https://docs.rs/poem-openapi/latest/src/poem_openapi/openapi.rs.html Generates an `Endpoint` that serves the OpenAPI Explorer UI. Requires the `openapi-explorer` feature. ```rust pub fn openapi_explorer(&self) -> impl Endpoint + 'static where T: OpenApi, W: Webhook, { crate::ui::openapi_explorer::create_endpoint(self.spec()) } ``` -------------------------------- ### Upload Binary Stream Source: https://docs.rs/poem-openapi/latest/poem_openapi/payload/struct.Binary.html Demonstrates how to upload binary data as a stream using the Binary payload with `poem::Body`. ```APIDOC ## POST /upload_stream ### Description Uploads binary data as a stream and returns its size. ### Method POST ### Endpoint /upload_stream ### Request Body - **data** (Binary) - Required - The binary data stream to upload. ### Response #### Success Response (200) - **response** (Result>) - The size of the uploaded binary data stream. ### Request Example ```json { "example": "application/octet-stream" } ``` ### Response Example ```json { "example": 6 } ``` ``` -------------------------------- ### Payload Implementations Source: https://docs.rs/poem-openapi/latest/poem_openapi/payload/trait.Payload.html Examples of types that implement the `Payload` trait, showcasing their specific content types. ```APIDOC ### impl Payload for Form #### const CONTENT_TYPE: &'static str = "application/x-www-form-urlencoded" ### impl Payload for Json #### const CONTENT_TYPE: &'static str = "application/json; charset=utf-8" ### impl Payload for Xml #### const CONTENT_TYPE: &'static str = "application/xml; charset=utf-8" ### impl Payload for Yaml #### const CONTENT_TYPE: &'static str = "application/yaml; charset=utf-8" ### impl + Send> Payload for Attachment #### const CONTENT_TYPE: &'static str = Binary::CONTENT_TYPE ### impl Payload for Base64 #### const CONTENT_TYPE: &'static str = "text/plain; charset=utf-8" ### impl Payload for Binary #### const CONTENT_TYPE: &'static str = "application/octet-stream" ### impl Payload for Html #### const CONTENT_TYPE: &'static str = "text/html; charset=utf-8" ### impl Payload for PlainText #### const CONTENT_TYPE: &'static str = "text/plain; charset=utf-8" ### impl + Send + 'static, E: Type + ToJSON> Payload for EventStream #### const CONTENT_TYPE: &'static str = "text/event-stream" ``` -------------------------------- ### Get String Length Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/struct.Email.html Returns the length of the string in bytes. Note that this is not the number of characters or graphemes. ```APIDOC ## pub fn len(&self) -> usize ### Description Returns the length of `self` in bytes. This length might not correspond to the number of characters or graphemes a human perceives. ### Returns - **usize**: The length of the string in bytes. ### Examples ``` let len = "foo".len(); assert_eq!(3, len); assert_eq!("ƒoo".len(), 4); // fancy f! assert_eq!("ƒoo".chars().count(), 3); ``` ``` -------------------------------- ### SecurityScheme Derive Macro Usage Source: https://docs.rs/poem-openapi/latest/poem_openapi/derive.SecurityScheme.html Demonstrates the basic usage of the `SecurityScheme` derive macro with available attributes for configuration. ```APIDOC ## SecurityScheme poem_openapi # Derive Macro SecurityScheme Copy item path Source Search Settings Help Summary ```rust #[derive(SecurityScheme)] { // Attributes available to this derive: #[oai] } ``` Expand description Define an OpenAPI Security Scheme. ## §Macro parameters Attribute| Description| Type| Optional ---|---|---|--- rename| Rename the security scheme.| string| Y ty| The type of the security scheme. (api_key, basic, bearer, oauth2, openid_connect)| string| N key_in| `api_key` The location of the API key. Valid values are “query”, “header” or “cookie”. (query, header, cookie)| string| Y key_name| `api_key` The name of the header, query or cookie parameter to be used..| string| Y bearer_format| `bearer` A hint to the client to identify how the bearer token is formatted. Bearer tokens are usually generated by an authorization server, so this information is primarily for documentation purposes.| string| Y flows| `oauth2` An object containing configuration information for the flow types supported.| OAuthFlows| Y openid_connect_url| OpenId Connect URL to discover OAuth2 configuration values.| string| Y checker| Specify a function to check the original authentication information and convert it to the return type of this function. This function must return `Option` or `poem::Result`, with `None` meaning a General Authorization error and an `Err` reflecting the error supplied.| string| Y ## §OAuthFlows Attribute| description| Type| Optional ---|---|---|--- implicit| Configuration for the OAuth Implicit flow| OAuthFlow| Y password| Configuration for the OAuth Resource Owner Password flow| OAuthFlow| Y client_credentials| Configuration for the OAuth Client Credentials flow| OAuthFlow| Y authorization_code| Configuration for the OAuth Authorization Code flow| OAuthFlow| Y ## §OAuthFlow Attribute| description| Type| Optional ---|---|---|--- authorization_url| `implicit` `authorization_code` The authorization URL to be used for this flow.| string| Y token_url| `password` `client_credentials` `authorization_code` The token URL to be used for this flow.| string| Y refresh_url| The URL to be used for obtaining refresh tokens.| string| Y scopes| The available scopes for the OAuth2 security scheme.| OAuthScopes| Y ``` -------------------------------- ### Get ParseError Message Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/struct.ParseError.html Returns a reference to the error message associated with the `ParseError` without consuming it. ```rust pub fn message(&self) -> &str ``` -------------------------------- ### Create OpenApiService Source: https://docs.rs/poem-openapi/latest/poem_openapi/struct.OpenApiService.html Constructor for OpenApiService. Initializes the OpenAPI container with the provided API, title, and version. ```rust pub fn new(api: T, title: impl Into, version: impl Into) -> Self ``` -------------------------------- ### Create Redoc Endpoint Source: https://docs.rs/poem-openapi/latest/src/poem_openapi/ui/redoc/mod.rs.html Creates a Poem web server endpoint that serves the Redoc OpenAPI documentation UI at the root path ('/'). It takes the OpenAPI specification as a string, generates the HTML, and returns it as an HTML response. ```rust use poem::{Endpoint, endpoint::make_sync, web::Html}; const REDOC_JS: &str = include_str!("redoc.standalone.js"); const REDOC_TEMPLATE: &str = r#" Redoc
"#; pub(crate) fn create_html(document: &str) -> String { REDOC_TEMPLATE .replace("{:script}", REDOC_JS) .replace("{:spec}", document) } pub(crate) fn create_endpoint(document: String) -> impl Endpoint { let ui_html = create_html(&document); poem::Route::new().at("/", make_sync(move |_| Html(ui_html.clone()))) } ``` -------------------------------- ### Example of as_mut_str() Source: https://docs.rs/poem-openapi/latest/poem_openapi/types/struct.Email.html Converts a String into a mutable string slice. This allows in-place modification of the string data. ```rust let mut s = String::from("foobar"); let s_mut_str = s.as_mut_str(); s_mut_str.make_ascii_uppercase(); assert_eq!("FOOBAR", s_mut_str); ``` -------------------------------- ### Create Rapidoc Endpoint (with rapidoc feature) Source: https://docs.rs/poem-openapi/latest/src/poem_openapi/openapi.rs.html Generates an `Endpoint` that serves the RapiDoc UI. Requires the `rapidoc` feature. ```rust pub fn rapidoc(&self) -> impl Endpoint + 'static where T: OpenApi, W: Webhook, { crate::ui::rapidoc::create_endpoint(self.spec()) } ```