1#![deny(missing_docs, missing_debug_implementations)]
34
35pub mod canvas;
36pub mod path;
37pub mod prelude;
38pub mod process;
39
40mod thread_rng;
41mod user_const;
42
43pub use euclid;
45pub use failure;
46pub use fart_2d_geom as geom;
47pub use fart_aabb as aabb;
48pub use lazy_static;
49pub use noise;
50pub use num_traits;
51pub use rand;
52pub use svg;
53
54pub use thread_rng::FartThreadRng;
55
56use failure::ResultExt;
57use std::env;
58use std::path::PathBuf;
59
60pub type Result<T> = ::std::result::Result<T, failure::Error>;
62
63#[derive(Debug)]
65pub struct Config {
66 file_name: PathBuf,
67 rng: FartThreadRng,
68}
69
70impl Config {
71 fn new() -> Result<Config> {
72 let file_name =
73 env::var("FART_FILE_NAME").context("missing required FART_FILE_NAME env var")?;
74 let file_name = PathBuf::from(file_name);
75
76 let rng = rng();
77
78 Ok(Config { file_name, rng })
79 }
80
81 #[inline]
85 #[deprecated(note = "Use `fart::rng()` instead.")]
86 pub fn rng(&mut self) -> &mut impl rand::Rng {
87 &mut self.rng
88 }
89}
90
91pub fn generate<F>(f: F) -> !
102where
103 F: FnOnce(&mut Config) -> Result<svg::Document>,
104{
105 let then = std::time::Instant::now();
106 let code = match try_generate(f) {
107 Ok(()) => {
108 eprintln!(
109 "Generated in {:?}",
110 std::time::Instant::now().duration_since(then)
111 );
112 0
113 }
114 Err(e) => {
115 eprintln!("Error: {}", e);
116 for c in e.iter_causes() {
117 eprintln!(" Caused by: {}", c);
118 }
119 1
120 }
121 };
122 std::process::exit(code);
123}
124
125fn try_generate<F>(f: F) -> Result<()>
126where
127 F: FnOnce(&mut Config) -> Result<svg::Document>,
128{
129 let mut config = Config::new().context("failed to read configuration")?;
130 let doc = f(&mut config).context("function supplied to `fart::generate` failed")?;
131 svg::save(&config.file_name, &doc).context("failed to save SVG to a file")?;
132 Ok(())
133}
134
135pub fn rng() -> FartThreadRng {
137 return FartThreadRng::default();
138}