1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#![deny(missing_docs, missing_debug_implementations)]
pub mod path;
pub mod prelude;
pub mod scene;
pub mod shape;
pub use euclid;
pub use fart_2d_geom;
pub use fart_aabb as aabb;
pub use failure;
pub use num_traits;
pub use rand;
pub use svg;
use failure::ResultExt;
use rand::SeedableRng;
use std::env;
use std::path::PathBuf;
use std::process;
use std::str;
pub type Result<T> = ::std::result::Result<T, failure::Error>;
#[derive(Debug)]
pub struct Config {
file_name: PathBuf,
rng: rand::rngs::SmallRng,
}
impl Config {
fn new() -> Result<Config> {
let file_name =
env::var("FART_FILE_NAME").context("missing required FART_FILE_NAME env var")?;
let file_name = PathBuf::from(file_name);
let seed = if let Ok(seed) = env::var("FART_RNG_SEED") {
str::parse::<u64>(&seed)
.context("failed to parse the FART_RNG_SEED env var as a u64")?
} else {
rand::random()
};
let rng = rand::rngs::SmallRng::seed_from_u64(seed);
Ok(Config { file_name, rng })
}
#[inline]
pub fn rng(&mut self) -> &mut impl rand::Rng {
&mut self.rng
}
}
pub fn generate<F>(f: F) -> !
where
F: FnOnce(&mut Config) -> Result<svg::Document>,
{
let code = match try_generate(f) {
Ok(()) => 0,
Err(e) => {
eprintln!("Error: {}", e);
for c in e.iter_causes() {
eprintln!(" Caused by: {}", c);
}
1
}
};
process::exit(code);
}
fn try_generate<F>(f: F) -> Result<()>
where
F: FnOnce(&mut Config) -> Result<svg::Document>,
{
let mut config = Config::new().context("failed to read configuration")?;
let doc = f(&mut config).context("function supplied to `fart::generate` failed")?;
svg::save(&config.file_name, &doc).context("failed to save SVG to a file")?;
Ok(())
}