我正在使用config-rs从TOML文件加载配置,我想将字符串反序列化为枚举。我尝试使用serde_derive的var stripecard = "cus_BwS21a7fAH22uk";
StripeCustomer customer;
StripeConfiguration.SetApiKey(ConfigurationManager.AppSettings["StripeApiKey"].ToString());
var customerService = new StripeCustomerService();
customer = customerService.Get(stripecard);
ViewBag.last4card = customer.Sources.Data[0].Card.Last4.ToString();
ViewBag.ExpMonth = customer.Sources.Data[0].Card.ExpirationMonth.ToString();
ViewBag.ExpYear = customer.Sources.Data[0].Card.ExpirationYear.ToString();
ViewBag.Name = customer.Sources.Data[0].Card.Name.ToString();
功能解决它,但我不知道如何返回合适的Error来满足函数签名。我怎样才能实现它?
我的依赖项:
deserialize_with
用于反序列化枚举config = "0.7"
serde_derive = "1.0"
serde = "1.0"
toml = "0.4"
的示例代码:
RotationPolicyType
deserialize_with 编译错误:
extern crate config;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate toml;
use std::env;
use config::{Config, Environment, File};
use std::path::PathBuf;
use serde;
use serde::de::Deserializer;
use serde::Deserialize;
#[derive(Debug, Deserialize, Clone)]
pub enum RotationPolicyType {
ByDuration,
ByDay,
}
#[derive(Debug, Deserialize, Clone)]
pub struct FileConfig {
pub rotations: i32,
#[serde(deserialize_with="deserialize_with")]
pub rotation_policy_type: RotationPolicyType,
}
#[derive(Debug, Deserialize, Clone)]
pub struct Settings {
pub threads: usize,
pub file_writer: FileConfig,
}
impl Settings {
pub fn new() -> Self {
let mut s = Config::new();
s.merge(File::with_name("config/default")).unwrap();
s.merge(File::with_name("config/local").required(false))
.unwrap();
s.merge(Environment::with_prefix("app")).unwrap();
s.deserialize().unwrap()
}
}
fn deserialize_with<D>(deserializer: D) -> Result<RotationPolicyType, D::Error> where D: Deserializer {
let s = String::deserialize(deserializer)?;
match s.as_ref() {
"ByDuration" => Ok(RotationPolicyType::ByDuration),
"ByDay" => Ok(RotationPolicyType::ByDay),
_ => Err(serde::de::Error::custom("error trying to deserialize rotation policy config"))
}
}
fn deserialize_with2<'de, D>(deserializer: &'de mut D) -> Result<RotationPolicyType, D::Error> where &'de mut D: Deserializer<'de> {
let s = String::deserialize(deserializer)?;
match s.as_ref() {
"ByDuration" => Ok(RotationPolicyType::ByDuration),
"ByDay" => Ok(RotationPolicyType::ByDay),
_ => Err(serde::de::Error::custom("error trying to deserialize rotation policy config"))
}
}
deserialize_with2 的编译错误:
error[E0106]: missing lifetime specifier
--> src/settings.rs:30:94
|
30 | fn deserialize_with<D>(deserializer: D) -> Result<RotationPolicyType, D::Error> where D: Deserializer {
| ^^^^^^^^^^^^ expected lifetime parameter
error: aborting due to previous error
答案 0 :(得分:3)
首先,您的示例编译得不够远,无法解决您所描述的错误。请注意下次生成MCVE。要让它在https://play.rust-lang.org上运行的加分点(可能,extern crate config
在您的示例中完全没有必要)。
修复所有编译问题后,只需修改功能API以匹配建议的in the serde docs
即可解决您的第一个错误-fn deserialize_with< D>(deserializer: D) -> Result<RotationPolicyType, D::Error> where D: Deserializer
+fn deserialize_with<'de, D>(deserializer: D) -> Result<RotationPolicyType, D::Error> where D: Deserializer<'de>
错误试图帮助你。它告诉你Deserializer
缺少一个生命周期参数。
第二个功能是告诉您D
没有关联的类型Error
。只有在D
实施Deserializer<'de>
时才能使用。但是您指定&'de mut D
实现Deserializer<'de>
。寻找这个问题的解决方案留给读者练习。
答案 1 :(得分:1)
根据@ oli-obk-ker的建议,解决方案非常简单:
use std::env;
use config::{Config, File, Environment};
use std::path::PathBuf;
use serde;
use serde::de::Deserializer;
use serde::Deserialize;
pub trait DeserializeWith: Sized {
fn deserialize_with<'de, D>(de: D) -> Result<Self, D::Error>
where D: Deserializer<'de>;
}
#[derive(Debug, Deserialize, Eq, PartialEq, Clone)]
pub enum RotationPolicyType {
ByDuration,
ByDay
}
impl DeserializeWith for RotationPolicyType {
fn deserialize_with<'de, D>(de: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
let s = String::deserialize(de)?;
match s.as_ref() {
"ByDuration" => Ok(RotationPolicyType::ByDuration),
"ByDay" => Ok(RotationPolicyType::ByDay),
_ => Err(serde::de::Error::custom("error trying to deserialize rotation policy config"))
}
}
}
#[derive(Debug, Deserialize, Clone)]
pub struct FileConfig {
pub rotations: i32,
#[serde(deserialize_with="RotationPolicyType::deserialize_with")]
pub rotation_policy_type: RotationPolicyType,
}
#[derive(Debug, Deserialize, Clone)]
pub struct Settings {
pub threads: i32,
pub file_writer: FileConfig,
}
impl Settings {
pub fn new() -> Self {
let mut s = Config::new();
s.merge(File::with_name("config/default")).unwrap();
s.merge(File::with_name("config/local").required(false)).unwrap();
s.merge(Environment::with_prefix("app")).unwrap();
s.deserialize().unwrap()
}
}