### Tide Example: Basic Redirect Setup Source: https://docs.rs/tide/latest/src/tide/redirect.rs Demonstrates how to set up a basic Tide web application with a root route and a redirect route using `Redirect::temporary`. ```Rust # use async_std::task::block_on; # fn main() -> Result<(), std::io::Error> { block_on(async { # use tide::Redirect; let mut app = tide::new(); app.at("/").get(|_| async { Ok("meow") }); app.at("/nori").get(Redirect::temporary("/")); app.listen("127.0.0.1:8080").await?; # # Ok(()) }) } ``` -------------------------------- ### Tide Application Listening Example Source: https://docs.rs/tide/latest/tide/struct.Server Illustrates how to create a new Tide application, define a root route, and then start listening for incoming connections on a specified IP address and port using the `app.listen()` method. ```Rust let mut app = tide::new(); app.at("/").get(|_| async { Ok("Hello, world!") }); app.listen("127.0.0.1:8080").await?; ``` -------------------------------- ### Tide Application Binding and Accepting Connections Example Source: https://docs.rs/tide/latest/tide/struct.Server Shows a more detailed server setup in Tide, where the application first binds to an address using `app.bind()`, iterates through listener information (e.g., for multiple ports), and then explicitly starts accepting connections with `listener.accept()`. ```Rust use tide::prelude::*; let mut app = tide::new(); app.at("/").get(|_| async { Ok("Hello, world!") }); let mut listener = app.bind("127.0.0.1:8080").await?; for info in listener.info().iter() { println!("Server listening on {}", info); } listener.accept().await?; ``` -------------------------------- ### Create New Tide Server Source: https://docs.rs/tide/latest/tide/fn.new Demonstrates how to create a new instance of the Tide web server and configure a basic GET route for the root path. It also shows how to start the server listening on a specified address. ```rust let mut app = tide::new(); app.at("/").get(|_| async { Ok("Hello, world!") }); app.listen("127.0.0.1:8080").await?; ``` -------------------------------- ### Serve Directory Example Source: https://docs.rs/tide/latest/src/tide/route.rs Example demonstrating how to serve static files from a directory using the `serve_dir` method on a Tide route. This maps a directory's contents to a specific URL path. ```Rust use tide::Server; use std::io; #[async_std::main] async fn main() -> Result<(), io::Error> { let mut app: Server<()> = tide::new(); // Serve contents of './public/images/' from the '/images/*' path app.at("/images").serve_dir("public/images/")?; app.listen("127.0.0.1:8080").await?; Ok(()) } ``` -------------------------------- ### Tide Application Route Definition Example Source: https://docs.rs/tide/latest/tide/struct.Server Demonstrates how to define a basic GET route at the root path ('/') using the `app.at()` method in Tide, and associate it with an asynchronous handler that returns a simple 'Hello, world!' string. ```Rust app.at("/").get(|_| async { Ok("Hello, world!") }); ``` -------------------------------- ### Create New Tide Server Source: https://docs.rs/tide/latest/tide/struct.Server Provides a basic example of creating a new tide server instance and setting up a simple GET endpoint for the root path. It demonstrates the server's ability to listen for incoming HTTP requests. ```rust let mut app = tide::new(); app.at("/").get(|_| async { Ok("Hello, world!") }); app.listen("127.0.0.1:8080").await?; ``` -------------------------------- ### SessionMiddleware Example Usage Source: https://docs.rs/tide/latest/tide/sessions/struct.SessionMiddleware Demonstrates how to integrate SessionMiddleware into a Tide application, including setting up a store, handling session data, and managing session lifecycle. ```rust let mut app = tide::new(); app.with(tide::sessions::SessionMiddleware::new( tide::sessions::MemoryStore::new(), b"we recommend you use std::env::var(\"TIDE_SECRET\").unwrap().as_bytes() instead of a fixed value" )); app.with(tide::utils::Before(|mut request: tide::Request<()>| async move { let session = request.session_mut(); let visits: usize = session.get("visits").unwrap_or_default(); session.insert("visits", visits + 1).unwrap(); request })); app.at("/").get(|req: tide::Request<()>| async move { let visits: usize = req.session().get("visits").unwrap(); Ok(format!("you have visited this website {} times", visits)) }); app.at("/reset") .get(|mut req: tide::Request<()>| async move { req.session_mut().destroy(); Ok(tide::Redirect::new("/")) }); ``` -------------------------------- ### Tide Session Middleware Customization Example Source: https://docs.rs/tide/latest/src/tide/sessions/middleware.rs Demonstrates how to customize Tide's `SessionMiddleware` using its builder pattern. This example shows setting cookie name, path, domain, SameSite policy, and session TTL. ```rust use tide::http::cookies::SameSite; use std::time::Duration; use tide::sessions::{SessionMiddleware, MemoryStore}; let mut app = tide::new(); app.with( SessionMiddleware::new(MemoryStore::new(), b"please do not hardcode your secret") .with_cookie_name("custom.cookie.name") .with_cookie_path("/some/path") .with_cookie_domain("www.rust-lang.org") .with_same_site_policy(SameSite::Lax) .with_session_ttl(Some(Duration::from_secs(1))) .without_save_unchanged(), ); ``` -------------------------------- ### Tide Server Nesting Example Source: https://docs.rs/tide/latest/src/tide/server.rs Demonstrates how to nest one Tide server within another, allowing for modular application structures. This example shows nesting with identical and different state types. ```rust #[cfg(test)] mod test { use crate as tide; #[test] fn allow_nested_server_with_same_state() { let inner = tide::new(); let mut outer = tide::new(); outer.at("/foo").get(inner); } #[test] fn allow_nested_server_with_different_state() { let inner = tide::with_state(1); let mut outer = tide::new(); outer.at("/foo").get(inner); } } ``` -------------------------------- ### Example: Add LogMiddleware to Tide Server Source: https://docs.rs/tide/latest/tide/log/struct.LogMiddleware Demonstrates how to instantiate and apply the LogMiddleware to a Tide server instance using the `with` method. This middleware is enabled by default. ```rust let mut app = tide::Server::new(); app.with(tide::log::LogMiddleware::new()); ``` -------------------------------- ### Create New Tide Server Source: https://docs.rs/tide/latest/src/tide/server.rs Demonstrates creating a new Tide server instance with default configuration. This is a common starting point for building web applications. ```Rust use async_std::task::block_on; fn main() -> Result<(), std::io::Error> { block_on(async { let mut app = tide::new(); app.at("/").get(|_| async { Ok("Hello, world!") }); app.listen("127.0.0.1:8080").await?; Ok(()) }) } ``` -------------------------------- ### Tide Logging Module: Start and Log Messages Source: https://docs.rs/tide/latest/src/tide/log/mod.rs This snippet demonstrates the usage of the tide crate's logging module, specifically how to start the logger and use various logging macros like info!, debug!, and error!. It relies on the kv-log-macro and optionally the femme crate for enhanced logging capabilities. ```Rust //! Event logging types. //! //! # Examples //! //! ```no_run //! use tide::log; //! //! log::start(); //! //! log::info!("Hello cats"); //! log::debug!("{} wants tuna", "Nori"); //! log::error!("We're out of tuna!"); //! log::info!("{} are hungry", "cats", { //! cat_1: "Chashu", //! cat_2: "Nori", //! }); //! ``` pub use kv_log_macro::{debug, error, info, log, trace, warn}; pub use kv_log_macro::{max_level, Level}; mod middleware; #[cfg(feature = "logger")] pub use femme::LevelFilter; pub use middleware::LogMiddleware; /// Start logging. #[cfg(feature = "logger")] pub fn start() { femme::start(); crate::log::info!("Logger started", { level: "Info" }); } /// Start logging with a log level. #[cfg(feature = "logger")] pub fn with_level(level: LevelFilter) { femme::with_level(level); crate::log::info!("Logger started", { level: format!("{}", level) }); } ``` -------------------------------- ### Example: Using Before Middleware Source: https://docs.rs/tide/latest/tide/utils/struct.Before Demonstrates how to use the `Before` middleware with a `tide` application. It shows setting an `Instant::now()` as a request extension, which can then be accessed by subsequent middleware or handlers. ```rust use tide::{utils, Request}; use std::time::Instant; let mut app = tide::new(); app.with(utils::Before(|mut request: Request<()>| async move { request.set_ext(Instant::now()); request })); ``` -------------------------------- ### Start Logging in Tide Source: https://docs.rs/tide/latest/tide/log/fn.start Initializes the logging system for the Tide web framework. This function is essential for enabling and managing log output within the application. ```rust pub fn start() // Start logging. ``` -------------------------------- ### Async Rust Endpoint Example (Tide) Source: https://docs.rs/tide/latest/tide/trait.Endpoint Demonstrates a simple asynchronous Rust endpoint for Tide that returns a String on GET requests. It uses `async fn` and `tide::Result` for handling responses. ```rust async fn hello(_req: tide::Request<()>) -> tide::Result { Ok(String::from("hello")) } let mut app = tide::Server::new(); app.at("/hello").get(hello); ``` -------------------------------- ### Tide Route Path Examples Source: https://docs.rs/tide/latest/src/tide/server.rs Illustrates various ways to define route paths in Tide, showcasing static segments, named wildcards, and catch-all wildcards for flexible URL matching. ```rust # let mut app = tide::Server::new(); app.at("/"); app.at("/hello"); app.at("add_two/:num"); app.at("files/:user/*"); app.at("static/*path"); app.at("static/:context/:/"); ``` -------------------------------- ### Tide Request Example Usage Source: https://docs.rs/tide/latest/src/tide/request.rs Demonstrates how to set up a basic Tide web server that handles POST requests to the root path, parsing JSON request bodies into an `Animal` struct. ```APIDOC APIDOC: Title: Tide Web Server POST Request Handling Description: Example of setting up a Tide web server to handle POST requests, parse form data, and return a response. Dependencies: tide, serde Example: ```rust let mut app = tide::new(); #[derive(Deserialize)] struct Animal { name: String, legs: u8 } app.at("/").post(|mut req: tide::Request<()>| async move { let animal: Animal = req.body_form().await?; Ok(format!("hello, {}! i've put in an order for {} shoes", animal.name, animal.legs)) }); // To run the server: // app.listen("localhost:8000").await?; ``` Usage: Send a POST request with form-encoded data: $ curl localhost:8000/ -d "name=chashu&legs=4" Expected Output: hello, chashu! i've put in an order for 4 shoes Example with URL-encoded name: $ curl localhost:8000/ -d "name=mary%20millipede&legs=750" Expected Output (if legs is too large for u8): number too large to fit in target type ``` -------------------------------- ### FailoverListener Example Usage Source: https://docs.rs/tide/latest/tide/listener/struct.FailoverListener Demonstrates how to create and use a FailoverListener in a tide application, adding multiple listeners via strings and TcpListeners. ```rust fn main() -> Result<(), std::io::Error> { async_std::task::block_on(async { tide::log::start(); let mut app = tide::new(); app.at("/").get(|_| async { Ok("Hello, world!") }); let mut listener = tide::listener::FailoverListener::new(); listener.add("127.0.0.1:8000")?; listener.add(async_std::net::TcpListener::bind("127.0.0.1:8001").await?)?; listener.add("http+unix://unix.socket")?; app.listen(listener).await?; Ok(()) }) } ``` -------------------------------- ### Tide Request Header Example Source: https://docs.rs/tide/latest/tide/struct.Request An example demonstrating how to access an HTTP header, specifically 'X-Forwarded-For', within a Tide request handler. ```rust use tide::Request; let mut app = tide::new(); app.at("/").get(|req: Request<()>| async move { // Example: Accessing the 'X-Forwarded-For' header assert_eq!(req.header("X-Forwarded-For").unwrap(), "127.0.0.1"); Ok("") }); app.listen("127.0.0.1:8080").await?; ``` -------------------------------- ### Tide Logging Example Source: https://docs.rs/tide/latest/tide/log/index Demonstrates how to use the logging macros provided by the tide crate to log messages at different levels (info, debug, error) and with structured data. ```rust use tide::log; log::start(); log::info!("Hello cats"); log::debug!("{} wants tuna", "Nori"); log::error!("We're out of tuna!"); log::info!("{} are hungry", "cats", { cat_1: "Chashu", cat_2: "Nori", }); ``` -------------------------------- ### Tide Application Routing and Server API Source: https://docs.rs/tide/latest/tide/struct.Server Comprehensive API documentation for the Tide web framework's core application methods. This includes defining routes with `at`, adding middleware with `with`, and managing the server lifecycle with `listen` and `bind`. It details method signatures, parameters, return types, and usage examples for each function. ```APIDOC pub fn at<'a>(&'a mut self, path: &[str]) -> Route<'a, State> - Description: Adds a new route at the given `path`, relative to the application root. Supports concrete segments, wildcard segments (`:name`), and catch-all wildcards (`*path`). - Parameters: - `path`: A slice of strings representing the route path. Can include concrete segments, `:name` for single segment wildcards, or `*path` for multi-segment catch-all wildcards. - Returns: `Route<'a, State>` - A Route object allowing further configuration (e.g., HTTP method handlers). - Usage Examples: app.at("/"); app.at("/hello"); app.at("add_two/:num"); app.at("files/:user/*"); app.at("static/*path"); app.at("static/:context/:"); pub fn with(&mut self, middleware: M) -> &mut Self where M: Middleware - Description: Adds middleware to the application. Middleware provides customization of the request/response cycle, such as compression, logging, or header modification. Middleware is processed in the order it is applied. - Parameters: - `middleware`: An instance of a type implementing the `Middleware` trait. - Returns: `&mut Self` - A mutable reference to the application instance, allowing method chaining. pub async fn listen>(self, listener: L) -> Result<(), std::io::Error> - Description: Asynchronously serves the application with the supplied listener. This is a shorthand for calling `Server::bind`, logging `ListenInfo`, and then calling `Listener::accept`. - Parameters: - `listener`: An object that can be converted into a listener, typically a network address string (e.g., "127.0.0.1:8080"). - Returns: `Result<(), std::io::Error>` - An empty `Ok` on successful listening, or an `Err` if an I/O error occurs. pub async fn bind>(self, listener: L) -> Result<>::Listener, std::io::Error> - Description: Asynchronously binds the listener. This starts the listening process by opening necessary network ports but does not yet accept incoming connections. `Listener::accept` should be called after this to start accepting connections. Useful for inspecting `ListenInfo` before accepting connections. - Parameters: - `listener`: An object that can be converted into a listener, typically a network address string. - Returns: `Result<>::Listener, std::io::Error>` - The bound listener instance on success, or an `Err` if an I/O error occurs. ``` -------------------------------- ### Tide CORS Middleware Configuration Example Source: https://docs.rs/tide/latest/tide/security/struct.CorsMiddleware Demonstrates how to create and configure a CorsMiddleware instance using builder pattern methods like `new`, `allow_methods`, `allow_origin`, and `allow_credentials`. ```rust use http_types::headers::HeaderValue; use tide::security::{CorsMiddleware, Origin}; let cors = CorsMiddleware::new() .allow_methods("GET, POST, OPTIONS".parse::().unwrap()) .allow_origin(Origin::from("*")) .allow_credentials(false); ``` -------------------------------- ### FailoverListener Example Usage (Rust) Source: https://docs.rs/tide/latest/src/tide/listener/failover_listener.rs Demonstrates how to create and use a FailoverListener to listen on multiple addresses. It shows adding string addresses and TcpListeners, and then binding the application. ```rust fn main() -> Result<(), std::io::Error> { async_std::task::block_on(async { tide::log::start(); let mut app = tide::new(); app.at("/").get(|_| async { Ok("Hello, world!") }); let mut listener = tide::listener::FailoverListener::new(); listener.add("127.0.0.1:8000")?; listener.add(async_std::net::TcpListener::bind("127.0.0.1:8001").await?)?; # if cfg!(unix) { listener.add("http+unix://unix.socket")?; # } # if false { // This line is commented out to prevent actual listening during doc tests app.listen(listener).await?; # } Ok(()) }) } ``` -------------------------------- ### Tide SSE Endpoint Example Source: https://docs.rs/tide/latest/src/tide/sse/mod.rs Demonstrates creating a Server-Sent Events (SSE) endpoint with Tide. This example shows how to send messages like 'fruit: banana' and 'fruit: apple' to clients. It requires `tide` and `async-std` for asynchronous operations. ```rust //! Server-Sent Events (SSE) types. //! //! # Errors //! //! Errors originating in the SSE handler will be logged. Errors originating //! during the encoding of the SSE stream will be handled by the backend engine //! the way any other IO error is handled. //! //! In the future we may introduce a better mechanism to handle errors that //! originate outside of regular endpoints. //! //! # Examples //! //! ```no_run //! # fn main() -> Result<(), std::io::Error> { async_std::task::block_on(async { //! # //! use tide::sse; //! //! let mut app = tide::new(); //! app.at("/sse").get(sse::endpoint(|_req, sender| async move { //! sender.send("fruit", "banana", None).await?; //! sender.send("fruit", "apple", None).await?; //! Ok(()) //! })); //! app.listen("localhost:8080").await?; //! # Ok(()) }) //! # } //! ``` ``` -------------------------------- ### Session Creation Example Source: https://docs.rs/tide/latest/tide/sessions/struct.Session Illustrates the creation of a new Session instance using `Session::new()`. It shows how to check for expiry and retrieve the cookie value. ```rust let session = Session::new(); assert_eq!(None, session.expiry()); assert!(session.into_cookie_value().is_some()); ``` -------------------------------- ### Tide Session Middleware Example Source: https://docs.rs/tide/latest/src/tide/sessions/middleware.rs Demonstrates how to integrate and use the SessionMiddleware in a Tide application. It shows setting up the middleware with a memory store and a secret key, and how to access and modify session data within request handlers. ```rust use tide::sessions::{SessionMiddleware, MemoryStore}; use tide::{Request, Response, Result, Server}; use async_std::task::block_on; fn main() { block_on(async { let mut app = tide::new(); // Initialize SessionMiddleware with a MemoryStore and a secret key. // The secret key should be securely managed, e.g., from environment variables. app.with(SessionMiddleware::new( MemoryStore::new(), b"a_very_secret_key_that_should_be_at_least_32_bytes_long" )); // Middleware to track visits per session app.with(tide::utils::Before(|mut request: Request<()>| async move { let session = request.session_mut(); let visits: usize = session.get("visits").unwrap_or_default(); session.insert("visits", visits + 1).unwrap(); request })); // Route to display visit count app.at("/").get(|req: Request<()>| async move { let visits: usize = req.session().get("visits").unwrap(); Ok(format!("You have visited this website {} times", visits)) }); // Route to reset the session app.at("/reset").get(|mut req: Request<()>| async move { req.session_mut().destroy(); Ok(tide::Redirect::new("/")) }); // Example of starting the server (not included in original snippet but common) // app.listen("127.0.0.1:8080").await.unwrap(); }); } ``` -------------------------------- ### Example Endpoint Usage Source: https://docs.rs/tide/latest/src/tide/endpoint.rs Demonstrates how to define and register simple asynchronous endpoints in Tide. It shows a basic `async fn` endpoint and an alternative using `impl Future` for compatibility. ```rust /// A simple endpoint that is invoked on a `GET` request and returns a `String`: /// /// ```no_run /// async fn hello(_req: tide::Request<()>) -> tide::Result { /// Ok(String::from("hello")) /// } /// /// let mut app = tide::Server::new(); /// app.at("/hello").get(hello); /// ``` /// /// An endpoint with similar functionality that does not make use of the `async` keyword would look something like this: /// /// ```no_run /// # use core::future::Future; /// fn hello(_req: tide::Request<()>) -> impl Future> { /// async_std::future::ready(Ok(String::from("hello"))) /// } /// /// let mut app = tide::Server::new(); /// app.at("/hello").get(hello); /// ``` ``` -------------------------------- ### Tide CorsMiddleware Example Usage Source: https://docs.rs/tide/latest/src/tide/security/cors.rs Demonstrates how to create and configure the CorsMiddleware for a Tide web application. It shows setting allowed methods, origins, and credentials. ```rust use http_types::headers::HeaderValue; use tide::security::{CorsMiddleware, Origin}; let cors = CorsMiddleware::new() .allow_methods("GET, POST, OPTIONS".parse::().unwrap()) .allow_origin(Origin::from("*")) .allow_credentials(false); ``` -------------------------------- ### Rust Usage Example: tide::log::log Source: https://docs.rs/tide/latest/tide/log/macro.log Demonstrates how to use the `log` macro from the tide crate for logging messages with different levels of detail and optional structured context. ```rust use kv_log_macro::info; info!("hello"); info!("hello",); info!("hello {}", "cats"); info!("hello {}", "cats",); info!("hello {}", "cats", {{ cat_1: "chashu", cat_2: "nori", }}); ``` -------------------------------- ### tide::listener::ToListener Examples Source: https://docs.rs/tide/latest/tide/listener/trait.ToListener Illustrates various ways to specify listeners for the `tide` server using string formats and collections of addresses. Supports platform-specific formats and concurrent listening. ```Rust use tide::Server; async fn main() -> tide::Result<()> { let mut app = Server::<()>::new(); // Example: Basic TCP listener app.listen("tcp://localhost:8000").await?; // Example: Binding to all interfaces on a port app.listen("tcp://0.0.0.0:8080").await?; // Example: Using http alias for tcp app.listen("http://localhost:9000").await?; // Example: Specifying multiple listeners concurrently app.listen(vec!["tcp://localhost:8000", "tcp://localhost:8001"]).await?; // Example: Resolving multiple socket addresses (e.g., IPv4 and IPv6) use std::net::ToSocketAddrs; app.listen("localhost:8000".to_socket_addrs()?.collect::>()).await?; // Example: Unix domain socket (Unix-specific) // app.listen("http+unix:///var/run/tide/socket").await?; // Example: Windows named pipe (Windows-specific) // app.listen(":3000").await?; Ok(()) } ``` -------------------------------- ### Create Tide HTTP Server with JSON Validation Source: https://docs.rs/tide/latest/tide Demonstrates setting up a Tide HTTP server that listens for POST requests on `/orders/shoes`. It expects a JSON body, deserializes it into an `Animal` struct, and returns a personalized confirmation message. Includes example `curl` commands for testing. ```Rust use tide::Request; use tide::prelude::*; #[derive(Debug, Deserialize)] struct Animal { name: String, legs: u8, } #[async_std::main] async fn main() -> tide::Result<()> { let mut app = tide::new(); app.at("/orders/shoes").post(order_shoes); app.listen("127.0.0.1:8080").await?; Ok(()) } async fn order_shoes(mut req: Request<()>) -> tide::Result { let Animal { name, legs } = req.body_json().await?; Ok(format!("Hello, {}! I've put in an order for {} shoes", name, legs).into()) } ``` ```Shell $ curl localhost:8080/orders/shoes -d '{ "name": "Chashu", "legs": 4 }' Hello, Chashu! I've put in an order for 4 shoes $ curl localhost:8080/orders/shoes -d '{ "name": "Mary Millipede", "legs": 750 }' number too large to fit in target type ``` -------------------------------- ### json! Macro Example: Basic Usage Source: https://docs.rs/tide/latest/tide/prelude/macro.json Demonstrates the basic usage of the json! macro to create a serde_json::Value object representing a JSON structure with nested objects and arrays. ```Rust let value = json!({ "code": 200, "success": true, "payload": { "features": [ "serde", "json" ], "homepage": null } }); ``` -------------------------------- ### Create Tide HTTP Server with JSON Validation Source: https://docs.rs/tide/latest/tide/index Demonstrates setting up a Tide HTTP server that listens for POST requests on `/orders/shoes`. It expects a JSON body, deserializes it into an `Animal` struct, and returns a personalized confirmation message. Includes example `curl` commands for testing. ```Rust use tide::Request; use tide::prelude::*; #[derive(Debug, Deserialize)] struct Animal { name: String, legs: u8, } #[async_std::main] async fn main() -> tide::Result<()> { let mut app = tide::new(); app.at("/orders/shoes").post(order_shoes); app.listen("127.0.0.1:8080").await?; Ok(()) } async fn order_shoes(mut req: Request<()>) -> tide::Result { let Animal { name, legs } = req.body_json().await?; Ok(format!("Hello, {}! I've put in an order for {} shoes", name, legs).into()) } ``` ```Shell $ curl localhost:8080/orders/shoes -d '{ "name": "Chashu", "legs": 4 }' Hello, Chashu! I've put in an order for 4 shoes $ curl localhost:8080/orders/shoes -d '{ "name": "Mary Millipede", "legs": 750 }' number too large to fit in target type ``` -------------------------------- ### Get HTTP Header Example Source: https://docs.rs/tide/latest/src/tide/request.rs Demonstrates how to retrieve an HTTP header from a Tide request using the `header` method. This example shows checking the 'X-Forwarded-For' header. ```rust use tide::Request; // ... inside a request handler ... let forwarded_for = req.header("X-Forwarded-For").unwrap(); assert_eq!(forwarded_for, "127.0.0.1"); // ... ``` -------------------------------- ### Get Route Parameter Example Source: https://docs.rs/tide/latest/src/tide/request.rs Illustrates how to extract a named route parameter from a Tide request using the `param` method. This example shows retrieving a 'name' parameter. ```rust use tide::{Request, Result}; async fn greet(req: Request<()>) -> Result { let name = req.param("name").unwrap_or("world"); Ok(format!("Hello, {}!", name)) } // ... in app setup ... // app.at("/hello/:name").get(greet); ``` -------------------------------- ### SSE Endpoint Example Source: https://docs.rs/tide/latest/tide/sse/index Demonstrates how to create a Server-Sent Events (SSE) endpoint using the tide Rust crate. It shows sending messages to a client and handling potential errors during the SSE stream. ```Rust use tide::sse; let mut app = tide::new(); app.at("/sse").get(sse::endpoint(|_req, sender| async move { sender.send("fruit", "banana", None).await?; sender.send("fruit", "apple", None).await?; Ok(()) })); app.listen("localhost:8080").await?; ``` -------------------------------- ### Tide Server API Documentation Source: https://docs.rs/tide/latest/tide/struct.Server API reference for the tide Server struct, detailing its methods for initialization and configuration. Includes `new` for basic server creation and `with_state` for stateful servers. ```APIDOC Server An HTTP server. Servers are built up as a combination of *state*, *endpoints* and *middleware*: * Server state is user-defined, and is provided via the [`Server::with_state`](struct.Server.html#method.with_state) function. The state is available as a shared reference to all app endpoints. * Endpoints provide the actual application-level code corresponding to particular URLs. The [`Server::at`](struct.Server.html#method.at) method creates a new *route* (using standard router syntax), which can then be used to register endpoints for particular HTTP request types. * Middleware extends the base Tide framework with additional request or response processing, such as compression, default headers, or logging. To add middleware to an app, use the [`Server::middleware`](struct.Server.html#structfield.middleware) method. Methods: Server::new() -> Self Creates a new Tide server. Server::with_state(state: State) -> Self Creates a new Tide server with shared application scoped state. Parameters: state: The shared application state. Must implement Clone, Send, Sync, and 'static. Returns: A new Server instance configured with the provided state. ``` -------------------------------- ### Tide Request Header Manipulation Source: https://docs.rs/tide/latest/tide/struct.Request Methods for accessing and modifying HTTP headers on a request. This includes getting headers by key, getting mutable references to headers, and inserting/setting headers. ```APIDOC pub fn header(&self, key: impl Into) -> Option<&HeaderValues> Retrieves an HTTP header by its key. Returns an Option containing the header values if found. pub fn header_mut(&mut self, name: impl Into) -> Option<&mut HeaderValues> Retrieves a mutable reference to an HTTP header by its name. pub fn insert_header(&mut self, name: impl Into, values: impl ToHeaderValues) -> Option Sets or updates an HTTP header with the given name and values. Returns the previous header values if they existed. ``` -------------------------------- ### Tide Basic POST API Example Source: https://docs.rs/tide/latest/src/tide/lib.rs Demonstrates how to create a Tide web server, define a POST endpoint that accepts JSON request bodies, and process the data. It includes a `curl` command to test the created API endpoint and shows expected output and error handling for invalid input. ```Rust use tide::Request; use tide::prelude::*; #[derive(Debug, Deserialize)] struct Animal { name: String, legs: u8, } #[async_std::main] async fn main() -> tide::Result<()> { let mut app = tide::new(); app.at("/orders/shoes").post(order_shoes); app.listen("127.0.0.1:8080").await?; Ok(()) } async fn order_shoes(mut req: Request<()>) -> tide::Result { let Animal { name, legs } = req.body_json().await?; Ok(format!("Hello, {}! I've put in an order for {} shoes", name, legs).into()) } ``` ```SH $ curl localhost:8080/orders/shoes -d '{ "name": "Chashu", "legs": 4 }' Hello, Chashu! I've put in an order for 4 shoes $ curl localhost:8080/orders/shoes -d '{ "name": "Mary Millipede", "legs": 750 }' number too large to fit in target type ``` -------------------------------- ### Tide Request Extension Management Source: https://docs.rs/tide/latest/tide/struct.Request APIs for managing request extensions, which are used to store and retrieve arbitrary data associated with a request. Supports getting, getting mutably, and setting extension values. ```APIDOC pub fn ext(&self) -> Option<&T> Retrieves a request extension value by type. Parameters: T: The type of the extension value to retrieve. Returns: An Option containing a reference to the extension value if found, otherwise None. pub fn ext_mut(&mut self) -> Option<&mut T> Retrieves a mutable reference to a request extension value by type. Parameters: T: The type of the extension value to retrieve. Returns: An Option containing a mutable reference to the extension value if found, otherwise None. pub fn set_ext(&mut self, val: T) -> Option Sets a request extension value. If an extension of the same type already exists, it is replaced. Parameters: val: The value to set as the extension. Returns: An Option containing the previously stored extension value if one existed, otherwise None. ``` -------------------------------- ### Using tide::utils::After Middleware Example Source: https://docs.rs/tide/latest/tide/utils/struct.After An example demonstrating how to apply the `After` middleware to a tide application. This middleware intercepts responses and can modify them based on conditions, such as HTTP status codes. ```rust use tide::{utils, http, Response}; let mut app = tide::new(); app.with(utils::After(|res: Response| async move { match res.status() { http::StatusCode::NotFound => Ok("Page not found".into()), http::StatusCode::InternalServerError => Ok("Something went wrong".into()), _ => Ok(res), } })); ``` -------------------------------- ### Manual Serialize Implementation Example Source: https://docs.rs/tide/latest/tide/convert/trait.Serialize Demonstrates how to manually implement the `serde::Serialize` trait for a custom Rust struct. This example shows the structure of the implementation, including using `serialize_struct` to define the fields and their values. ```rust use serde::ser::{Serialize, SerializeStruct, Serializer}; struct Person { name: String, age: u8, phones: Vec, } // This is what #[derive(Serialize)] would generate. impl Serialize for Person { fn serialize(&self, serializer: S) -> Result where S: Serializer, { let mut s = serializer.serialize_struct("Person", 3)?; s.serialize_field("name", &self.name)?; s.serialize_field("age", &self.age)?; s.serialize_field("phones", &self.phones)?; s.end() } } ``` -------------------------------- ### Tide Session Support Overview Source: https://docs.rs/tide/latest/tide/sessions/index Provides a high-level overview of tide's session management strategy. It explains how sessions attach data to browser sessions for retrieval on subsequent visits and mentions the default guest session behavior. ```APIDOC Module sessions # Tide session support This document provides a high-level overview of tide’s approach to sessions. For implementation and examples, please refer to [SessionMiddleware](struct.SessionMiddleware.html "struct tide::sessions::SessionMiddleware") Sessions allows tide to securely attach data to a browser session allowing for retrieval and modification of this data within tide on subsequent visits. Session data is generally only retained for the duration of a browser session. Tide’s session implementation provides guest sessions by default, meaning that all web requests to a session-enabled tide host will have a cookie attached, whether or not there is anything stored in that client’s session yet. ``` -------------------------------- ### Rust Example: Implementing Serialize for a Struct Source: https://docs.rs/tide/latest/tide/prelude/trait.Serialize A practical example demonstrating how to manually implement the `Serialize` trait for a Rust struct (`Person`) using Serde. This showcases the typical structure generated by `#[derive(Serialize)]`. ```rust use serde::ser::{Serialize, SerializeStruct, Serializer}; struct Person { name: String, age: u8, phones: Vec, } // This is what #[derive(Serialize)] would generate. impl Serialize for Person { fn serialize(&self, serializer: S) -> Result where S: Serializer, { let mut s = serializer.serialize_struct("Person", 3)?; s.serialize_field("name", &self.name)?; s.serialize_field("age", &self.age)?; s.serialize_field("phones", &self.phones)?; s.end() } } ``` -------------------------------- ### Tide Server Creation API Source: https://docs.rs/tide/latest/src/tide/lib.rs Provides functions to create new Tide web server instances. `tide::new()` creates a server with no shared state, while `tide::with_state()` allows initializing the server with custom, clonable, and thread-safe application state. ```APIDOC /// Create a new Tide server. /// /// # Examples /// /// ```no_run /// # use async_std::task::block_on; /// # fn main() -> Result<(), std::io::Error> { block_on(async { /// # /// let mut app = tide::new(); /// app.at("/").get(|_| async { Ok("Hello, world!") }); /// app.listen("127.0.0.1:8080").await?; /// # /// # Ok(()) }) /// # } /// ``` #[must_use] pub fn new() -> server::Server<()> { ... } /// Create a new Tide server with shared application scoped state. /// /// Application scoped state is useful for storing items /// /// # Examples /// /// ```no_run /// # use async_std::task::block_on; /// # fn main() -> Result<(), std::io::Error> { block_on(async { /// # /// use tide::Request; /// /// The shared application state. /// #[derive(Clone)] /// struct State { /// name: String, /// } /// // Define a new instance of the state. /// let state = State { /// name: "Nori".to_string() /// }; /// // Initialize the application with state. /// let mut app = tide::with_state(state); /// app.at("/").get(|req: Request| async move { /// Ok(format!("Hello, {}!", &req.state().name)) /// }); /// app.listen("127.0.0.1:8080").await?; /// # /// # Ok(()) }) /// # } /// ``` pub fn with_state(state: State) where State: Clone + Send + Sync + 'static, { ... } ``` -------------------------------- ### ConcurrentListener::new() Source: https://docs.rs/tide/latest/tide/listener/struct.ConcurrentListener Creates a new, empty ConcurrentListener instance. This is the starting point for configuring multiple listeners. ```rust pub fn new() -> Self ``` -------------------------------- ### Redirect Example Usage Source: https://docs.rs/tide/latest/tide/struct.Redirect Demonstrates how to use the Redirect struct within a tide route handler to return a redirect response. ```rust async fn route_handler(request: Request<()>) -> tide::Result { if let Some(product_url) = next_product() { Ok(Redirect::new(product_url).into()) } else { //... } } ``` -------------------------------- ### Get Response Body Length Source: https://docs.rs/tide/latest/tide/struct.Response Retrieves the length of the response body. This method returns an Option containing the size of the body in bytes. ```Rust pub fn len(&self) -> Option ``` -------------------------------- ### Tide Server Constructor Source: https://docs.rs/tide/latest/tide/fn.new Provides the signature for the `new` function, which is used to construct a new Tide server instance. This is the entry point for creating a web application with the Tide framework. ```APIDOC tide::new() -> Server<()> Creates a new Tide server. Returns: A new `Server` instance, ready to be configured with routes and middleware. ``` -------------------------------- ### ConcurrentListener::info: Get Listener Information Source: https://docs.rs/tide/latest/src/tide/listener/concurrent_listener.rs Implements the `info` method for the `Listener` trait. It collects and returns a vector of `ListenInfo` for all the transports managed by this ConcurrentListener. ```rust fn info(&self) -> Vec { self.listeners .iter() .map(|listener| listener.info().into_iter()) .flatten() .collect() } ``` -------------------------------- ### Tide POST Endpoint with Query Parameters Source: https://docs.rs/tide/latest/src/tide/request.rs Demonstrates setting up a Tide web server with a POST endpoint at `/pages`. This endpoint accepts `size` and `offset` query parameters, deserializing them into a `Page` struct. Includes examples of how different query parameter inputs affect the response and potential error cases. ```Rust use tide::prelude::* #[derive(Deserialize)] #[serde(default)] struct Page { size: u8, offset: u8, } impl Default for Page { fn default() -> Self { Self { size: 25, offset: 0, } } } async fn main() -> Result<(), std::io::Error> { let mut app = tide::new(); app.at("/pages").post(|req: tide::Request<()>| async move { let page: Page = req.query()?; Ok(format!("page {}, with {} items", page.offset, page.size)) }); // Example usage with curl: // $ curl localhost:8000/pages // page 0, with 25 items // // $ curl localhost:8000/pages?offset=1 // page 1, with 25 items // // $ curl localhost:8000/pages?offset=2&size=50 // page 2, with 50 items // // $ curl localhost:8000/pages?size=5000 // failed with reason: number too large to fit in target type // // $ curl localhost:8000/pages?size=all // failed with reason: invalid digit found in string // app.listen("localhost:8000").await?; Ok(()) } ``` -------------------------------- ### Rust Any::type_id - Get Type ID Source: https://docs.rs/tide/latest/tide/struct.Error Retrieves the unique `TypeId` of an object implementing the `Any` trait. This is useful for runtime type identification. ```Rust fn type_id(&self) -> TypeId ``` -------------------------------- ### Tide Request: Get Content Type Source: https://docs.rs/tide/latest/src/tide/request.rs Extracts the `Content-Type` header from the request and parses it into a `Mime` type. This is essential for handling request bodies. ```Rust /// Get the request content type as a `Mime`. /// /// This gets the request `Content-Type` header. /// /// [Read more on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) #[must_use] pub fn content_type(&self) -> Option ```