#rust
#Ржавчина
Вопрос:
#[derive(Debug, Deserialize)]
struct S3StorageConfig {
url: String,
}
#[derive(Debug, Deserialize)]
struct LocalStorageConfig {
root: std::path::PathBuf,
}
#[derive(Debug, Deserialize)]
struct StorageConfig {
storage_type: String
}
#[derive(Debug, Deserialize)]
pub struct Config {
storages: Vec<StorageConfig>
}
impl Config {
pub fn new(path:Option<std::path::PathBuf>) -> Result<Self, config::ConfigError> {
let mut cfg = config::Config::default();
if let Some(file_path) = path {
cfg.merge(config::File::from(file_path)).unwrap();
}
cfg.merge(config::Environment::with_prefix("datastore"))?;
cfg.try_into()
}
}
Предположим, я хочу иметь конфигурацию, которая имеет
[[storages]]
type: s3
url: ...
и
[[storages]]
type: local
root: ...
И когда config это делает try_into
, он может находить эти структуры и присваивать их правильным структурам по милости type
поля.
Какую магию мне нужно сделать, чтобы это произошло?
Спасибо,
Комментарии:
1. Итак, в зависимости от
type
поля вы хотитеtry_into
вернуть либо aS3StorageConfig
, либо aLocalStorageConfig
? Из которого вы затем хотите вернутьсяConfig::new
?2. Вы смотрели на представления Enum в Serde docs?
Ответ №1:
Итак, я не уверен на 100%, чего вы пытаетесь достичь здесь, но вы можете сериализовать / десериализовать в нужные вам типы serde
и использовать enum
вместо этого.
Пример:
// This enum takes the place of your 'S3StorageConfig' and 'LocalStorageConfig'.
#[derive( Serialize, Deserialize, Debug )]
#[serde( tag = "type" )]
enum Storage {
Cloud{ url: String },
Local{ root: PathBuf },
}
fn main( ) {
let vec = vec![
Storage::Cloud{ url: "www.youtube.com".to_string( ) },
Storage::Local{ root: PathBuf::from( "C:\Windows\Fonts" ) },
];
let storage = serde_json::to_string( amp;vec ).unwrap( );
let vec: Vec<Storage> = serde_json::from_str( amp;storage ).unwrap( );
println!( "{:#?}", vec );
}
Теперь вы вернете Storage
enum
вариант из своего Config
класса.
Вам не нужно impl
TryInto
, если это направление, которое вы решили выбрать.
impl Config {
pub fn new( ) -> Result<Storage, config::ConfigError> {
// Read in the file here and use 'serde' to deserialize the
// content of the file into the correct enum variant that you
// can now return.
}
}
Комментарии:
1. Спасибо, это означает, что я не могу использовать ящик конфигурации, но я думаю, это нормально?