use std::fs::File;
use std::io::{Write, BufReader, BufRead};
#[derive(Default)]
pub struct BufData{
filepath:String,
data:Vec<DataType>,
}
enum DataType {
Notes(String),
Data((String,String)),
}
impl BufData {
pub fn new()->Self{
Self { filepath:"default.iii".to_string(),..Default::default() }
}
pub fn loadfromiii(filepath:&str)->Result<Self,&'static str>{
let mut data = Vec::new();
if let Ok(file)=File::open(filepath){
for idx in BufReader::new(file).lines(){
if let Ok(iidx) = idx{
if iidx.trim().starts_with("#"){
data.push(DataType::Notes(iidx));
}else{
let cc:Vec<&str> = iidx.trim().split("=").collect();
if cc.len() == 2{
data.push(DataType::Data((cc[0].trim().to_string(),cc[1].trim().to_string())));
}
}
}
}
Ok(Self{filepath:filepath.to_string(),data:data})
}else{
Err("load file fail")
}
}
fn onlywrite(&self,path:&str)->Result<(),&'static str>{
if let Ok(mut f) = File::create(path){
let mut bufstr = String::new();
for idx in &self.data{
match idx {
DataType::Data((s1,s2))=>{
bufstr.push_str(&format!("{} = {}\r\n",s1,s2));
},
DataType::Notes(commet)=>{
bufstr.push_str(&commet);
bufstr.push_str("\r\n");
},
}
}
if let Ok(_) = f.write(bufstr.as_bytes()){
return Ok(());
}
}
Err("write err")
}
pub fn save(&self,newfilepath:Option<&str>)->Result<(),&'static str>{
if let Some(pth) = newfilepath{
self.onlywrite(pth)
}else{
self.onlywrite(&self.filepath)
}
}
pub fn getvalue<T: std::str::FromStr>(&self,key:&str)->Result<T,()>{
for idx in &self.data{
if let DataType::Data((s1,s2))=idx{
if &key.to_string() == s1{
if let Ok(ss) = s2.parse::<T>(){
return Ok(ss);
}
}
}
}
return Err(());
}
pub fn chgvalue<T:std::fmt::Display>(&mut self,key:&str,value:T){
for idx in &mut self.data{
if let DataType::Data((s1,s2))=idx{
if &key.to_string() == s1{
s2.clear();
s2.push_str(&value.to_string());
return;
}
}
}
self.data.push(DataType::Data((key.to_string(),value.to_string())));
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn crate1(){
let mut cc = BufData::new();
cc.chgvalue("c1", "value");
cc.chgvalue("c2", "value2");
cc.chgvalue("c3", "value3");
if let Ok(_) = cc.save(None){
println!("file write success")
};
}
#[test]
fn readwrite(){
if let Ok(mut cc) = BufData::loadfromiii("default.iii"){
cc.chgvalue("c3", "ccc3");
cc.chgvalue("c5", "5c");
if let Ok(_) = cc.save(None){
println!("file write success")
};
};
}
#[test]
fn readvalue(){
if let Ok(cc) = BufData::loadfromiii("default.iii"){
if let Ok(v) = cc.getvalue::<String>("c2"){
println!("K:{},V:{}","c2",v);
}
if let Ok(v) = cc.getvalue::<String>("c5"){
println!("K:{},V:{}","c5",v);
}
};
}
#[test]
fn getnumbervalue()->Result<(),()>{
let mut cc = BufData::new();
cc.chgvalue("c2", "33");
cc.chgvalue("c4", &true.to_string());
let Ok(value) = cc.getvalue::<u32>("c2") else {return Err(())};
assert!(33==value);
let Ok(value) = cc.getvalue::<bool>("c4") else {return Err(());};
assert!(true==value);
Ok(())
}
}