Одним из способов обобщения для нескольких целевых структур может быть использование serde .
В случае нестандартного формата должен быть реализован десериализатор,
но вместо такой реализации
Стоит рассмотреть формат данных, поддерживаемый сообществом, если пользовательский формат является подмножеством или похож на стандартный.
Похоже, что ваш формат является подмножеством формата TOML : в этом случае используйте toml .
#[macro_use]
extern crate serde_derive;
#[derive(Serialize, Deserialize, Debug)]
struct Data {
field1: Option<String>,
field2: Option<u32>,
field3: Option<bool>,
field4: Option<std::net::Ipv4Addr>
}
fn main() {
let serialized = r#"
field1="something"
field2=556
field3=true
field4="10.0.0.1"
"#;
let deserialized: Data = toml::from_str(&serialized).unwrap();
println!("{:?}", deserialized);
}
Если ваш формат не совсем "стандартно" совместим, ищите способ преобразования закодированных данных перед десериализацией: например, если field1
и field4
не являются заключенными в кавычки строками, то подстановка шаблона на основе regex май работает:
#[macro_use]
extern crate serde_derive;
use std::borrow::Cow;
use regex::{Captures, Regex};
#[derive(Serialize, Deserialize, Debug)]
struct Data {
field1: Option<String>,
field2: Option<u32>,
field3: Option<bool>,
field4: Option<std::net::Ipv4Addr>,
}
fn reformat_string(before: &str) -> Cow<str> {
let matcher : Regex = Regex::new(
r"(?P<f>field1|field4)=(?P<val>[\w.]+)"
).unwrap();
matcher.replace_all(before, |cap: &Captures| {
let mut buff = String::new();
if &cap[1] == "field1" || &cap[1] == "field4" {
cap.expand("$f='$val'", &mut buff);
}
Cow::Owned(buff)
})
}
fn main() {
let serialized = r#"
field1=something
field2=556
field3=true
field4=10.0.0.1
"#;
let transformed = reformat_string(serialized);
let deserialized: Data = toml::from_str(&transformed).unwrap();
println!("{:?}", deserialized);
}