Я использую config в качестве средства для загрузки внешних данных в мою программу, которая использует serde в фоновом режиме для десериализации, но мне нужна возможность, чтобы конкретное поле могло бытьодин из нескольких типов.Поскольку я совершенно новичок в Rust, найденная мною документация не имеет большого смысла.
Как сделать так, чтобы initial_value
мог быть одного из нескольких типов:
String
i32
bool
[i32,i32]
Я понимаю, что могу использовать атрибут deserialize_with
, чтобы перейти к пользовательскому декодеру, но за этим я немного растерялся.
Вот мой код:
use std::collections::HashMap;
use std::fs;
use config_rs::{Config, ConfigError, File};
#[derive(Debug, Deserialize)]
enum InitialValues {
String,
i32,
bool,
}
#[derive(Debug, Deserialize)]
struct Component {
component: String,
initial_value: InitialValues,
}
#[derive(Debug, Deserialize)]
struct Template {
feature_packs: Vec<String>,
components: Vec<Component>,
}
type Name = String;
type Type = String;
#[derive(Debug, Deserialize)]
pub struct Templates {
templates: HashMap<Name, Template>,
}
impl Templates {
pub fn new(file: &str) -> Result<Self, ConfigError> {
let mut templates = Config::new();
templates.merge(File::with_name(file)).unwrap();
templates.try_into()
}
}
#[derive(Debug)]
pub struct Manager {
pub templates: HashMap<Type, Templates>,
}
impl Manager {
pub fn new(dir: &str) -> Self {
let mut manager = Self {
templates: HashMap::new(),
};
'paths: for raw_path in fs::read_dir(dir).unwrap() {
let path = raw_path.unwrap().path();
let file_path = path.clone();
let type_name = path.clone();
let templates = match Templates::new(type_name.to_str().unwrap()) {
Ok(templates) => templates,
Err(message) => {
println!("TemplateManager: file({:?}), {}", &file_path, message);
continue 'paths;
}
};
manager.templates.insert(
file_path.file_stem().unwrap().to_str().unwrap().to_owned(),
templates,
);
}
manager
}
}
Пример файла конфигурации:
---
templates:
orc:
feature_packs:
- physical
- basic_identifiers_mob
components:
- component: char
initial_value: T
goblin:
feature_packs:
- physical
- basic_identifiers_mob
components:
- component: char
initial_value: t