Skip to content

Commit 0fbb524

Browse files
author
Lloyd Lobo
committed
feat: use paths in settings for output
1 parent 28c4b1c commit 0fbb524

File tree

4 files changed

+48
-39
lines changed

4 files changed

+48
-39
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,7 @@ indicatif = "0.17.3"
1616
log = "0.4.17"
1717
once_cell = "1.17.0"
1818
pretty_env_logger = "0.4.0"
19+
serde = "1.0.152"
20+
serde_derive = "1.0.152"
1921
# termion = "2.0.1"
2022
# tui = { version = "0.19.0", features = ["termion"] }

settings.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
debug = false
22
priority = 32
33
key = "189rjfadoisfj8923fjio"
4+
text = "mandelbrot.txt"
5+
image = "mandelbrot.png"

src/bin/mandelbrot.rs

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
1-
use std::{collections::HashMap, env, sync::RwLock};
1+
use std::{env, path::Path, sync::RwLock};
22

33
use clap::{command, Arg, ArgMatches};
44
use config::{builder::DefaultState, Config, ConfigBuilder};
55
use console::Style;
66
use indicatif::{ProgressBar, ProgressStyle};
77
use log::{info, LevelFilter::Info};
8+
use mandelbrot::mandelbrot_ascii;
89
use once_cell::sync::Lazy;
910
use pretty_env_logger::env_logger::Builder;
11+
use serde::{Deserialize, Serialize};
1012

1113
const ITERATIONS: u32 = 255;
1214
const WIDTH: u32 = 800;
1315
const HEIGHT: u32 = 800;
1416
const DEFAULT_SETTINGS_FILE: &str = "settings.toml";
1517
const DEFAULT_IMAGE_PATH: &str = "mandelbrot.png";
18+
const DEFAULT_TEXT_PATH: &str = "mandelbrot.txt";
1619

1720
static CONFIG_BUILDER: Lazy<RwLock<ConfigBuilder<DefaultState>>> =
1821
Lazy::new(|| RwLock::new(Config::builder()));
@@ -29,18 +32,15 @@ fn main() {
2932
fn try_main() -> anyhow::Result<()> {
3033
let mut curr_path = env::current_dir().unwrap();
3134
curr_path.push(DEFAULT_SETTINGS_FILE);
32-
// TODO: Directly mutate `CONFIG_BUILDER` without assigning it.
33-
let settings_builder: ConfigBuilder<DefaultState> = CONFIG_BUILDER
35+
let settings_new: Config = CONFIG_BUILDER
3436
.write()
3537
.unwrap()
3638
.clone()
3739
.set_default("verbose", "1")? // This is not in the settings file.
3840
.add_source(config::File::with_name(&curr_path.to_string_lossy()))
39-
.add_source(config::Environment::with_prefix("APP"));
40-
// Does not take ownership of `ConfigBuilder` to allow later reuse.
41-
let settings_new: Config = settings_builder.build_cloned()?;
42-
// {"key": "189rjfadoisfj8923fjio", "verbose": "1", "priority": "32", "debug": "false"}
43-
let _map_new = settings_new.try_deserialize::<HashMap<String, String>>()?;
41+
.add_source(config::Environment::with_prefix("APP"))
42+
.build_cloned()?;
43+
let config_manager: ConfigManager = settings_new.try_deserialize()?;
4444

4545
// Parse clap args.
4646
let matches: ArgMatches = command!()
@@ -69,9 +69,9 @@ fn try_main() -> anyhow::Result<()> {
6969
info!("Rendering image Mandelbrot set as {}", Style::new().bold().apply_to("ASCII"));
7070
let pb = ProgressBar::new(WIDTH as u64 * HEIGHT as u64);
7171
style_progress_bar(&pb);
72-
let image = mandelbrot::mandelbrot_ascii::collect_ascii();
72+
let image = mandelbrot_ascii::collect_ascii();
7373
pb.finish();
74-
mandelbrot::mandelbrot_ascii::print_ascii(image);
74+
mandelbrot_ascii::print_ascii(image);
7575
}
7676

7777
if let Some(_text) = matches.get_one::<String>("text") {
@@ -81,8 +81,8 @@ fn try_main() -> anyhow::Result<()> {
8181
);
8282
let pb = ProgressBar::new(WIDTH as u64 * HEIGHT as u64);
8383
style_progress_bar(&pb);
84-
let image = mandelbrot::mandelbrot_ascii::collect_ascii();
85-
mandelbrot::mandelbrot_ascii::write_ascii_to_file(image);
84+
let image = mandelbrot_ascii::collect_ascii();
85+
mandelbrot_ascii::write_ascii_to_file(image, Path::new(&config_manager.text));
8686
pb.finish_with_message("Wrote ascii to file");
8787
}
8888

@@ -93,7 +93,13 @@ fn try_main() -> anyhow::Result<()> {
9393
);
9494
let pb = ProgressBar::new(WIDTH as u64 * HEIGHT as u64);
9595
style_progress_bar(&pb);
96-
mandelbrot::mandelbrot_img::compose(WIDTH, HEIGHT, ITERATIONS).save(DEFAULT_IMAGE_PATH)?;
96+
if config_manager.image.is_empty() {
97+
mandelbrot::mandelbrot_img::compose(WIDTH, HEIGHT, ITERATIONS)
98+
.save(DEFAULT_IMAGE_PATH)?;
99+
} else {
100+
mandelbrot::mandelbrot_img::compose(WIDTH, HEIGHT, ITERATIONS)
101+
.save(config_manager.image)?;
102+
}
97103
pb.finish_with_message("Saved image to file");
98104
}
99105

@@ -111,36 +117,36 @@ fn style_progress_bar(pb: &ProgressBar) {
111117

112118
/// `build_config_settings` is a wrapper around `config` crate.
113119
///
114-
/// # Examples
115-
///
116-
/// ```rust,ignore
117-
/// use config::Config;
118-
/// use mandelbrot::build_config_settings;
119-
///
120-
/// fn main() {
121-
/// // TODO: Add `tempfile` crate or `include_str!()`.
122-
/// let settings = build_config_settings("settings.toml")?;
123-
/// let map = settings.try_deserialize::<HashMap<String, String>>().unwrap();
124-
/// let expect = r#"{"key": "189rjfadoisfj8923fjio", "debug": "false", "priority": "32"}"#;
125-
/// assert_eq!(map, expect);
126-
/// }
127-
/// ```
128-
/// # Panics
129-
///
130-
/// Panics if .
131-
///
132-
/// # Errors
133-
///
134-
/// This function will return an error if .
120+
/// * `build_cloned` method - Does not take ownership of `ConfigBuilder` to allow later reuse.
121+
/// let map_new = settings_new.try_deserialize::<HashMap<String, String>>()?;
122+
// NOTE: Directly mutate `CONFIG_BUILDER` without assigning it.
135123
pub fn build_config_settings(path: &str) -> Result<Config, config::ConfigError> {
136124
let mut curr_path = env::current_dir().unwrap();
137125
curr_path.push(path);
138126

127+
// Add in `./settings.toml`
128+
// Add in settings from the environment (with a prefix of APP)
129+
// Eg.. `APP_DEBUG=1 ./target/app` would set the `debug` key
139130
Config::builder()
140-
// Add in `./settings.toml`
141131
.add_source(config::File::with_name(&curr_path.to_string_lossy()))
142-
// Add in settings from the environment (with a prefix of APP)
143-
// Eg.. `APP_DEBUG=1 ./target/app` would set the `debug` key
144132
.add_source(config::Environment::with_prefix("APP"))
145133
.build()
146134
}
135+
136+
#[derive(Debug, Deserialize, Serialize)]
137+
struct ConfigManager {
138+
text: String,
139+
image: String,
140+
}
141+
142+
impl Default for ConfigManager {
143+
fn default() -> Self {
144+
Self::new()
145+
}
146+
}
147+
148+
impl ConfigManager {
149+
fn new() -> Self {
150+
Self { text: DEFAULT_TEXT_PATH.to_string(), image: DEFAULT_IMAGE_PATH.to_string() }
151+
}
152+
}

src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,7 @@ pub mod mandelbrot_ascii {
192192
}
193193

194194
/// Prints the ASCII image generated by the `collect_ascii` function
195-
pub fn write_ascii_to_file(image: HashMap<usize, char>) {
196-
let path = Path::new("mandelbrot.txt");
195+
pub fn write_ascii_to_file(image: HashMap<usize, char>, path: &Path) {
197196
let mut buffer = File::create(path).unwrap(); // if !path.exists() { }
198197

199198
for y in 0..HEIGHT {

0 commit comments

Comments
 (0)