texc_utils/
lib.rs

1//! TexCreate Utilities Library <br>
2//! This library is intended to contain functions for subcommands <br>
3//! Developer: Mustafif Khan <br>
4//! Project: TexCreate  <br>
5//! License: MIT & GPLv2 <br>
6
7
8use async_std::fs::{File, read_to_string};
9use async_std::io::prelude::*;
10use async_std::io::stdin;
11use texc_config::{TexCreateError, TexCreateResult};
12use texc_config::Config;
13
14/// Initializes a TexCreate Project
15pub async fn init() -> TexCreateResult<()> {
16    let config = Config::default();
17    // Create single mode config
18    println!("Use default settings? (yes/no): ");
19    let mut def_settings = String::new();
20    stdin().read_line(&mut def_settings).await?;
21    return match def_settings.trim() {
22        "yes" => {
23            let s = config.to_string().unwrap();
24            let mut file = File::create("config.toml").await?;
25            file.write_all(s.as_bytes()).await?;
26            Ok(())
27        }
28        "no" => {
29            let conf = ask_questions().await;
30            let s = conf.to_string().unwrap();
31            let mut file = File::create("config.toml").await?;
32            file.write_all(s.as_bytes()).await?;
33            Ok(())
34        }
35        _ => Err(TexCreateError::Invalid(
36            "settings option chosen!".to_string(),
37        )),
38    };
39}
40
41/// Updates TexCreate
42pub fn update() -> TexCreateResult<()> {
43    let cmd = std::process::Command::new("cargo")
44        .arg("install")
45        .arg("texcreate")
46        .output()?;
47    if cmd.status.success() {
48        println!("{}", String::from_utf8_lossy(&cmd.stdout));
49        Ok(())
50    } else {
51        Err(TexCreateError::Invalid(
52            "TexCreate update failed!".to_string(),
53        ))
54    }
55}
56fn valid_templates() -> (Vec<&'static str>, Vec<&'static str>) {
57    (
58        vec![
59            "Basic", "Math", "Theatre", "Code", "Novel", "Beamer", "Lachaise", "Lachaise-Mod", "Dictionary", "News"
60        ],
61        vec![
62            "Designed for simple documents",
63            "Designed for math focused documents",
64            "Designed to write plays/shows",
65            "Designed to write code using listings",
66            "Designed to write well...novels",
67            "Designed to create presentations",
68            "Designed for school assignments and academic papers",
69            "Modified version of Lachaise Template, changes in colours/design",
70            "Designed to write your own dictionary",
71            "Designed to write columned newspapers"
72        ],
73    )
74}
75/// Lists all templates
76pub fn list() {
77    let mut temp = valid_templates();
78    println!("=======================");
79    println!("  Available Templates  ");
80    println!("=======================");
81    for t in 0..temp.0.len() {
82        println!("==> {}: {}", temp.0[t], temp.1[t.clone()]);
83    }
84    println!("=======================");
85}
86
87async fn ask_questions() -> Config {
88    println!("Enter Author: ");
89    let mut author = String::new();
90    stdin().read_line(&mut author).await.unwrap();
91    println!("Enter Title: ");
92    let mut title = String::new();
93    stdin().read_line(&mut title).await.unwrap();
94    println!("Enter Date: ");
95    let mut date = String::new();
96    stdin().read_line(&mut date).await.unwrap();
97    println!("Enter Project Name: ");
98    let mut project_name = String::new();
99    stdin().read_line(&mut project_name).await.unwrap();
100    list();
101    println!("Enter Template: ");
102    let mut template = String::new();
103    stdin().read_line(&mut template).await.unwrap();
104    println!("Enter Paper Size: ");
105    let mut paper_size = String::new();
106    stdin().read_line(&mut paper_size).await.unwrap();
107    println!("Enter Document Class: ");
108    let mut document_class = String::new();
109    stdin().read_line(&mut document_class).await.unwrap();
110    println!("Enter Font Size: ");
111    let mut font_size = String::new();
112    stdin().read_line(&mut font_size).await.unwrap();
113    println!("Default Project Structure? (y/n): ");
114    let mut def_structure = String::new();
115    stdin().read_line(&mut def_structure).await.unwrap();
116    let def_structure = match def_structure.as_str() {
117        "y" => None,
118        "n" => Some(true),
119        _ => None,
120    };
121    Config::new(
122        author.trim(),
123        title.trim(),
124        date.trim(),
125        project_name.trim(),
126        &Some(template),
127        &None,
128        paper_size.trim(),
129        font_size.trim().parse().unwrap(),
130        vec![],
131        def_structure,
132        document_class.trim(),
133    )
134}
135
136fn edit_item(config: &mut Config, field: &Option<String>, field_name: &str, fs: Option<u8>) {
137    let field = match field.to_owned() {
138        Some(f) => f,
139        None => return println!("No changes to {}", field_name),
140    };
141    let fs = match fs {
142        Some(f) => f,
143        None => 11,
144    };
145    match field_name {
146        "author" => {
147            println!(
148                "Changed {} from {} to {}",
149                field_name, &config.author, &field
150            );
151            config.author = field;
152        }
153        "title" => {
154            println!(
155                "Changed {} from {} to {}",
156                field_name, &config.title, &field
157            );
158            config.title = field;
159        }
160        "date" => {
161            println!("Changed {} from {} to {}", field_name, &config.date, &field);
162            config.date = field
163        }
164        "rename" => {
165            println!("Renamed project to {}", &field);
166            config.project_name = field
167        }
168        "template" => {
169            println!(
170                "Changed {} from {} to {}",
171                field_name, &config.template.as_ref().unwrap(), &field
172            );
173            config.template = Some(field)
174        }
175        "paper_size" => {
176            println!(
177                "Changed {} from {} to {}",
178                field_name, &config.paper_size, &field
179            );
180            config.paper_size = field
181        }
182        "font_size" => {
183            println!(
184                "Changed {} from {} to {}",
185                field_name,
186                &config.font_size.to_string(),
187                &field
188            );
189            config.font_size = fs
190        }
191        "doc_class" => {
192            println!(
193                "Changed {} from {} to {}",
194                field_name, &config.document_class, &field
195            );
196            config.document_class = field
197        }
198        "add_package" => {
199            println!("Added package {}", &field);
200            let s: String = field;
201            config.packages.push(s);
202        }
203        "rm_package" => {
204            println!("Removed package {}", &field);
205            let mut v = Vec::new();
206            for i in &config.packages {
207                if i.as_str() != field.as_str() {
208                    v.push(i.to_string());
209                }
210            }
211            config.packages = v;
212        }
213        "only_files" => {
214            println!("Changing only-files structure to {}", &field);
215            let field = match field.as_str() {
216                "true" => true,
217                "false" => false,
218                _ => false,
219            };
220            config.only_files = Some(field);
221        }
222        _ => println!("Nothing to do"),
223    }
224}
225/// Runs the edit command for TexCreate by changing any field specified
226pub async fn edit(
227    author: Option<String>,
228    title: Option<String>,
229    date: Option<String>,
230    rename: Option<String>,
231    template: Option<String>,
232    paper_size: Option<String>,
233    font_size: Option<u8>,
234    doc_class: Option<String>,
235    add_package: Option<String>,
236    rm_package: Option<String>,
237    only_files: Option<String>,
238) -> TexCreateResult<()> {
239    let mut config = Config::from_string(read_to_string("config.toml").await?).unwrap();
240    edit_item(&mut config, &author, "author", None);
241    edit_item(&mut config, &title, "title", None);
242    edit_item(&mut config, &date, "date", None);
243    edit_item(&mut config, &rename, "rename", None);
244    edit_item(&mut config, &template, "template", None);
245    edit_item(&mut config, &paper_size, "paper_size", None);
246    edit_item(&mut config, &doc_class, "doc_class", None);
247    edit_item(&mut config, &None, "font_size", font_size);
248    edit_item(&mut config, &add_package, "add_package", None);
249    edit_item(&mut config, &rm_package, "rm_package", None);
250    edit_item(&mut config, &only_files, "only_files", None);
251    let mut file = File::create("config.toml").await?;
252    file.write_all(config.to_string().unwrap().as_bytes())
253        .await?;
254
255    Ok(())
256}