使用config-rs时出现'missing field'错误的原因排查
问题
使用config-rs执行cargo run时,在s.try_deserialize()步骤出现Err(missing field "web3_node_provider")错误。按照config-rs层级示例编写代码,无法通过web3_node_provider.ethereum_mainnet_node_url_http读取配置,但改用Web3NodeProvider.url却能正常工作。相关代码及配置文件如下:
Rust代码
use config::{Config, ConfigError, Environment, File}; use serde::Deserialize; #[derive(Debug, Deserialize)] #[allow(unused)] struct Web3NodeProvider { ethereum_mainnet_node_url_http: String, alchemy_api_key: String, } #[derive(Debug, Deserialize)] #[allow(unused)] pub struct Settings { web3_node_provider: Web3NodeProvider, } impl Settings { pub fn new() -> Result<Self, ConfigError> { let s = Config::builder() .add_source(File::with_name("config/default")) .add_source(File::with_name("config/local").required(false)) .add_source(Environment::with_prefix("app")) .build()?; s.try_deserialize() } } fn main() { let settings = Settings::new(); println!("{:?}", settings); }
default.toml
[Web3NodeProvider] ethereum_mainnet_node_url_http = "https://eth-mainnet.g.alchemy.com/v2/" alchemy_api_key = "alchemy-api-key"
local.toml
[Web3NodeProvider] alchemy_api_key = "randomapikey"
解决方案
问题核心是TOML配置节的命名与Rust结构体字段名不匹配:
- Rust中
Settings结构体的字段为蛇形命名的web3_node_provider - TOML文件里的节却是大驼峰命名的
Web3NodeProvider
serde默认按蛇形命名规则进行反序列化,两者命名规则不匹配就会导致字段缺失错误。以下两种方式均可修复:
方式一:修改TOML配置的节名
将配置文件中的[Web3NodeProvider]改为[web3_node_provider],与Rust字段名保持一致:
修改后的default.toml:
[web3_node_provider] ethereum_mainnet_node_url_http = "https://eth-mainnet.g.alchemy.com/v2/" alchemy_api_key = "alchemy-api-key"
修改后的local.toml:
[web3_node_provider] alchemy_api_key = "randomapikey"
方式二:给Rust结构体字段添加serde别名
如果不想改动配置文件,可给Settings中的web3_node_provider字段添加#[serde(rename = "Web3NodeProvider")]属性,让serde识别TOML中的节名:
修改后的Rust结构体代码:
#[derive(Debug, Deserialize)] #[allow(unused)] pub struct Settings { #[serde(rename = "Web3NodeProvider")] web3_node_provider: Web3NodeProvider, }
任选一种方式即可解决错误,实现配置的正常反序列化。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

