Skip to content

Commit

Permalink
feat: update merge logic
Browse files Browse the repository at this point in the history
  • Loading branch information
wangxdmm committed Jan 3, 2024
1 parent bfc16f6 commit 722daf3
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 50 deletions.
59 changes: 29 additions & 30 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::{
fs::{self, File},
fs::File,
io::{Error, ErrorKind, Read},
};

use crate::config::{parse_config, Config};
use crate::config::{self, parse_config, Config};
use crate::{core::*, tpl::INIT_CONFIG};
use ansi_term::Colour;
use clap::{Parser, Subcommand};
Expand Down Expand Up @@ -109,23 +109,21 @@ pub fn run() -> Result<(), Error> {
let config = Config::new(cli.dir)?;
println!("{}", Colour::Yellow.paint("docs:"));

config.walk(|n, doc| {
config.walk_config(|n, doc| {
if let Some(f) = filter {
if let Some(doc) = doc {
if doc.contains(n, f) {
config.view(n, *detail)
}
if doc.contains(n, f) {
config.view(n, *detail)
}
} else {
config.view(n, *detail)
config.view(&n, *detail)
}
})
}
Some(Commands::Init { force, url, merge }) => {
let home = dirs::home_dir();
let is_force = *force;
let should_merge = *merge;
let mut config = String::from(INIT_CONFIG);
let mut write_config = String::new();
let mut remote_config = String::new();

if let Some(home) = home {
Expand All @@ -135,10 +133,13 @@ pub fn run() -> Result<(), Error> {
}

if config_path.exists() {
config.clear();
File::open(&config_path)?.read_to_string(&mut config)?;
File::open(&config_path)?.read_to_string(&mut write_config)?;

let mut user_config = parse_config(&config)?;
let mut user_config = if write_config.is_empty() {
Config::new_empty()
} else {
parse_config(&write_config)?
};

if should_merge {
let rc_config = parse_config(&remote_config)?;
Expand All @@ -148,18 +149,22 @@ pub fn run() -> Result<(), Error> {
}
});

config = toml::to_string(&user_config).unwrap();
} else {
if !is_force {
println!(
"❗Config file already exist, If you want to overwrite it, add '-f'"
);
return Ok(());
}
write_config = user_config.to_string()?;
}

if is_force && !remote_config.is_empty() {
config::save(&config_path, &remote_config)?;
return Ok(());
}
fs::write(&config_path, config)?;

config::save(&config_path, &write_config)?;
} else {
fs::write(&config_path, config)?;
write_config = String::from(if remote_config.is_empty() {
INIT_CONFIG
} else {
&remote_config
});
config::save(&config_path, &write_config)?;
}

println!("Success init config in {}", &config_path.display())
Expand All @@ -171,16 +176,10 @@ pub fn run() -> Result<(), Error> {
let config = Config::new(cli.dir)?;
if cli.name.is_none() {
println!("❓Please select one of the names below to see, or just use '-s' to search by google \neg: doc xx -s 👇:");
config.walk(|n, doc| {
config.walk_config(|n, doc| {
print!(
"{} ",
if doc.is_some() {
Colour::Green
.paint(doc.unwrap().get_printed_name(n))
.to_string()
} else {
String::new()
}
Colour::Green.paint(doc.get_printed_name(n)).to_string()
)
});
println!("\n");
Expand Down
77 changes: 57 additions & 20 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use crate::core::{Doc, OpenOption};
use crate::error::Error as DocError;
use crate::tpl::INIT_CONFIG;
use ansi_term::Colour;
use serde::{Deserialize, Serialize};

use std::fs;
use std::{
collections::HashMap,
collections::BTreeMap,
fs::File,
io::{Error, ErrorKind, Read},
path::{Path, PathBuf},
Expand All @@ -13,7 +15,7 @@ use std::{
#[derive(Deserialize, Debug, Serialize)]
pub struct Config {
pub loc: Option<PathBuf>,
pub map: HashMap<String, Doc>,
pub map: BTreeMap<String, Doc>,
}

impl Config {
Expand Down Expand Up @@ -49,6 +51,32 @@ impl Config {
}
}

pub fn new_empty() -> Config {
Config {
loc: None,
map: BTreeMap::new(),
}
}

pub fn save(&self) -> Result<(), Error> {
let Config { loc, map } = self;
let mut content = String::from(INIT_CONFIG);

if !map.is_empty() {
content = self.to_string()?
}

if let Some(loc) = loc {
fs::write(loc, content)?
}

Ok(())
}

pub fn to_string(&self) -> Result<String, Error> {
toml::to_string(self).map_err(|err| Error::new(ErrorKind::InvalidData, err))
}

pub fn open(&self, name: &str, option: &OpenOption) -> Result<(), Error> {
match self.find(name) {
Some(doc) => {
Expand All @@ -61,11 +89,9 @@ impl Config {
name
);

self.walk(|n, doc| {
if let Some(doc) = doc {
if doc.contains(n, &name[0..1]) {
println!("{}", Colour::Yellow.paint(doc.get_printed_name(n)));
}
self.walk_config(|n, doc| {
if doc.contains(n, &name[0..1]) {
println!("{}", Colour::Yellow.paint(doc.get_printed_name(n)));
}
});
Ok(())
Expand All @@ -79,16 +105,14 @@ impl Config {
}
}

pub fn walk<T>(&self, mut call: T)
// TODO remove it ??
pub fn walk_config<T>(&self, mut call: T)
where
T: FnMut(&String, Option<&Doc>),
T: FnMut(&String, &Doc),
{
let mut ks: Vec<_> = self.map.keys().collect();

ks.sort();

for n in ks {
call(n, self.map.get(n))
// BTree has already sorted
for (n, doc) in &self.map {
call(n, &doc)
}
}

Expand All @@ -98,10 +122,10 @@ impl Config {
match self.map.get(name) {
Some(_) => doc_name = name.to_string(),
None => {
self.walk(|n, doc| {
if let Some(Doc {
self.walk_config(|n, doc| {
if let Doc {
full: Some(full), ..
}) = doc
} = doc
{
if full == name {
doc_name = n.to_string()
Expand All @@ -124,7 +148,7 @@ pub fn parse_config(cont: &str) -> Result<Config, Error> {
match parse_result {
Ok(value) => Ok(value),
Err(err) => {
println!("Parse Error, error content is: {}", cont);
println!("Parse Error, error content is: {}", cont);
Err(Error::new(ErrorKind::InvalidData, err))
}
}
Expand All @@ -135,4 +159,17 @@ pub fn read(loc: &PathBuf) -> Result<Config, Error> {
File::open(&loc)?.read_to_string(&mut cont)?;

parse_config(&cont)
}
}

pub fn save(loc: &PathBuf, content: &str) -> Result<(), Error> {
fs::write(
loc,
if content.is_empty() {
INIT_CONFIG
} else {
content
},
)?;

Ok(())
}

0 comments on commit 722daf3

Please sign in to comment.