Depot

Depot 是用於保存一次請求中涉及到的臨時數據。中介軟體可以將自己處理的臨時數據放入 Depot,供後續程序使用。

當一個伺服器接收到一個客戶瀏覽器發來的請求後會創建一個 Depot 的實例。這個實例會在所有的中介軟體和 Handler 處理完請求後被銷毀。

比如說,我們可以在登入的中介軟體中設置 current_user,然後在後續的中介軟體或者 Handler 中讀取當前用戶資訊。

快速理解

Depot 用於在請求處理過程中存儲和共享數據。它實現了一個類型安全的數據容器,支援兩種主要使用模式:

  1. 鍵值存儲:通過 insert/get 方法存取字符串鍵關聯的值
  2. 類型注入:通過 inject/obtain 方法基於類型存取值

如示例所示,Depot 特別適用於在中介軟體和處理程序之間傳遞數據。中介軟體可以在 Depot 中設置值(如用戶資訊、認證狀態),後續處理程序可以獲取這些值,無需重複計算或查詢。Depot 的設計確保了在整個請求處理鏈中數據的一致性和可訪問性,是構建複雜 Web 應用的核心工具。

main.rs
Cargo.toml
use-depot/src/main.rs
use salvo::prelude::*;

#[handler]
async fn set_user(depot: &mut Depot) {
depot.insert("user", "client");
}
#[handler]
async fn hello(depot: &mut Depot) -> String {
format!(
    "Hello {}",
    depot.get::<&str>("user").copied().unwrap_or_default()
)
}

#[tokio::main]
async fn main() {
tracing_subscriber::fmt().init();

let router = Router::new().hoop(set_user).goal(hello);

let acceptor = TcpListener::new("0.0.0.0:5800").bind().await;
Server::new(acceptor).serve(router).await;
}

通過insertget 設置和取出數據

如上所示,可以通過 insertkeyvalue 插入到 Depot 中。對於這一類型的值,直接用 get 取出。

depot.insert("a", "b");
assert_eq!(depot.get::<&str>("a").copied().unwrap(), "b")

如果不存在這個 key,或者 key 存在,但是類型不匹配,則返回 None

通過injectobtain 設置和取出數據

有時,存在一些不需要關係具體 key,對於這種類型也存在唯一實例的情況。可以使用 inject 插入數據,然後使用 obtain 取出數據。它們不需要你提供 key

depot.inject(Config::new());
depot.obtain::<Config>();

Depot 結構體方法概覽

類別方法描述
創建/容量new()創建空 Depot
with_capacity(capacity)創建指定容量的 Depot
capacity()獲取容量
inner()獲取內部 HashMap 引用
類型注入/獲取inject<V>(value)按類型注入值
obtain<T>()獲取注入值引用
obtain_mut<T>()獲取注入值可變引用
contains<T>()檢查是否包含特定類型
scrape<T>()移除並返回注入值
鍵值操作insert(key, value)插入鍵值對
get<V>(key)獲取鍵對應值引用
get_mut<V>(key)獲取鍵對應值可變引用
contains_key(key)檢查是否包含特定鍵
remove<V>(key)移除鍵並返回值
delete(key)刪除鍵值對