M Cargo.toml => Cargo.toml +16 -1
@@ 5,6 5,21 @@ authors = ["Ben Lovy <ben@deciduously.com>"]
edition = "2018"
license = "BSD-3-Clause"
+[features]
+default = ["bin"]
+
+bin = [] # maybe structopt here
+
[dependencies]
-lazy_static = "1.4">
\ No newline at end of file
+lazy_static = "1.4"
+thiserror = "1.0"
+toml = "0.5"
+
+[dependencies.serde]
+version = "1.0"
+features = ["derive"]
+
+[dev-dependencies]
+
+pretty_assertions = "0.6"<
\ No newline at end of file
M src/bin/fcalc.rs => src/bin/fcalc.rs +6 -2
@@ 1,5 1,9 @@
-use std::env::var;
+//! Simple CLI to request recipes.
+
+#![cfg(feature = "bin")]
+
use lazy_static::lazy_static;
+use std::env::var;
lazy_static! {
pub static ref VERSION: String = var("CARGO_PKG_VERSION").unwrap();
@@ 7,4 11,4 @@ lazy_static! {
fn main() {
println!("fcalc {} - Factorio Calculator", *VERSION);
-}>
\ No newline at end of file
+}
A src/error.rs => src/error.rs +13 -0
@@ 0,0 1,13 @@
+//! Top-level error struct
+
+use std::io;
+use thiserror::Error;
+
+#[derive(Debug, Error)]
+pub enum FcalcError {
+ #[error("Could not read input data file")]
+ FileError(#[from] io::Error),
+}
+
+/// Export convenient Result type carrying this error.
+pub type Result<T> = std::result::Result<T, FcalcError>;
A src/item.rs => src/item.rs +55 -0
@@ 0,0 1,55 @@
+//! An item is something the player can hold. Some are raw, some are craftable.
+
+use lazy_static::lazy_static;
+use serde::Deserialize;
+
+lazy_static! {
+ pub static ref ITEMS: Items = Items::new();
+}
+
+// /// All items, raw or otherwise, implement this trait.
+// // TODO is this even necessary?
+// pub trait Item: Display {}
+
+/// A base-level raw material, not craftable.
+#[derive(Debug, Deserialize)]
+pub struct RawMaterial {
+ name: String,
+}
+
+#[derive(Debug, Deserialize)]
+pub struct Product {
+ name: String,
+}
+
+/// The top-level Items struct, containing all supported items read from TOML.
+#[derive(Debug, Deserialize)]
+pub struct Items {
+ raw_materials: Vec<RawMaterial>,
+ products: Vec<Product>,
+}
+
+impl Items {
+ fn new() -> Self {
+ Self::default()
+ }
+}
+
+impl Default for Items {
+ fn default() -> Self {
+ let input = include_str!("items.toml");
+ toml::from_str(input).expect("Could not read items file")
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+ use pretty_assertions::assert_eq;
+ #[test]
+ fn it_loads_all_items() {
+ let items = Items::new();
+ assert_eq!(items.raw_materials.len(), 2);
+ assert_eq!(items.products.len(), 1);
+ }
+}
A src/items.toml => src/items.toml +10 -0
@@ 0,0 1,10 @@
+# All the items supported
+
+[[raw_materials]]
+name = "Coal"
+
+[[raw_materials]]
+name = "Iron Ore"
+
+[[products]]
+name = "Iron Plate"<
\ No newline at end of file
M src/lib.rs => src/lib.rs +10 -7
@@ 1,8 1,11 @@
+//! fcalc is a library for calculating Factorio recipe inputs.
+//!
+//!
+//! When compiled with the "bin" feature, sepcified by default,
+//! it ships a CLI binary called `fcalc` for convenient usage.
-#[cfg(test)]
-mod tests {
- #[test]
- fn it_works() {
- assert_eq!(2 + 2, 4);
- }
-}
+mod error;
+mod item;
+mod recipe;
+
+pub use error::{FcalcError, Result};
A src/recipe.rs => src/recipe.rs +3 -0
@@ 0,0 1,3 @@
+//! A recipe tracks the cost to produce an item.
+#[derive(Debug)]
+pub struct Recipe;