背景
最近有个公司有个迁移配置的需求,要将原来项目中的配置迁移到内部的配置中心,需要把 *.properties
转化为 *.yml
来用,本着节约时间能写代码绝不动手的原则(事实证明比手动改格式更费时间 qwq),练练手写个 parser
Show me the code
use std::{cell::RefCell, collections::HashMap, rc::Rc, time};
mod test;
type Res = Result<(), Box<dyn std::error::Error>>;
type Ptr<T> = Rc<RefCell<T>>;
fn main() -> Res {
let now = time::Instant::now();
let conf = to_ptr(Prop {
name: String::from("parent"),
val: None,
sub: Some(HashMap::new()),
});
let path = "./resource/test.properties";
let prop_file = std::fs::read_to_string(path)?;
for line in prop_file.lines() {
let line = line.replace(" ", "");
if line.len() != 0 && line.get(0..=0).unwrap() != "#" {
parse(line.clone(), conf.clone());
}
}
println!("{:?}", conf);
let yaml = to_yaml(conf, 0);
println!("result: \n{yaml}");
println!("parse spend: {:?}", now.elapsed());
Ok(())
}
fn to_yaml(conf: Rc<RefCell<Prop>>, dep: usize) -> String {
let mut res = "".to_string();
if let Some(map) = conf.borrow().sub.as_ref() {
if map.len() != 0 {
let sub_str = if dep != 0 {
format!("{}{}: \n", " ".repeat(dep - 1), conf.borrow().name.clone())
} else {
"".to_string()
};
for (_, sub_prop) in map.iter() {
res = format!("{}{}", res, to_yaml(sub_prop.clone(), dep + 1));
}
res = format!("{sub_str}{res}");
} else {
res = format!("{}{}: {}\n", " ".repeat(dep - 1), conf.borrow().name.clone(), conf.borrow().val.clone().unwrap());
}
}
if dep == 1 {
format!("{res}\n")
} else {
format!("{res}")
}
}
fn to_ptr<T>(ele: T) -> Ptr<T> {
Rc::new(RefCell::new(ele))
}
#[derive(Debug)]
struct Prop {
name: String,
val: Option<String>,
sub: Option<HashMap<String, Ptr<Prop>>>,
}
fn parse(line: String, father: Ptr<Prop>) -> Option<Ptr<Prop>>{
if let None = line.find("=") {
return None;
}
let mut ptr: Ptr<Prop> = to_ptr(Prop {
name: String::new(),
val: None,
sub: None,
});
for (idx, c) in line.chars().enumerate() {
if c == '.' || c == '=' {
let (name, suffix) = line.split_at(idx);
let name = String::from(name);
if let Some(ref mut map) = father.borrow_mut().sub {
match map.get(&name) {
Some(val) => {
ptr = val.clone();
}
None => {
ptr.borrow_mut().name = name.clone();
ptr.borrow_mut().sub = Some(HashMap::new());
map.insert(name.clone(), ptr.clone());
}
};
}
match suffix.get(0..=0) {
Some(".") => {
parse(suffix.get(1..).unwrap().to_owned(), ptr.clone());
}
Some("=") => {
ptr.borrow_mut().val = match suffix.get(1..) {
Some(val) => Some(String::from(val)),
None => Some(String::new()),
};
}
_ => {}
};
break;
}
}
Some(ptr.clone())
}
总结
优雅是不可能优雅的,能力就是这个样子,能跑就行是我们的人生信条 =v=