Task:
Expand "${HOME}/dir1/${DIR2}/dir3" to a string which does not contain any "${}".
Here is my solution,it return a String everytime which maybe inefficient.
So, Can you come up with a better one?
use std::env;
fn env_finder(name:&str)->Option<String>{
if let Some(v) = env::var_os(name) {
return Some(env_recur(v.to_str().unwrap()));
}else{
return None;
}
}
//expand ${HOME}/dir1/${DIR2}/dir3
fn env_recur(path:&str)-> String{
//cur_recur +=1;
//if cur_recur > MAX_RECUR{return;}
let mut s=path.splitn(2,"${");
let head=s.next();
let mut re = head.unwrap().to_owned();
//re.push_str(head.unwrap());
let tail=s.next();
match tail {
Some(t) => {
let mut s2=t.splitn(2,"}");
let name=s2.next().unwrap();
let tail2=s2.next();
match tail2{
Some(t2) => {
if let Some(val) = env::var_os(name){
re.push_str(&env_recur(val.to_str().unwrap()));
}
if t2 != ""{
re.push_str(&env_recur(t2));
}
},
None => {}
}
},
None => {}
}
return re;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
env::set_var("A","dir1/${B}/dir3");
env::set_var("B","dir4/${C}/${C}");
env::set_var("C","dir5");
assert_eq!(env_finder("A"),Some("dir1/dir4/dir5/dir5/dir3".to_owned()));
}
}