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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
//! Loads YAML configuration files (.yaml/.yml) into a structure for easy usage. //! //! # Basic usage: //! //! ```rust //! #[macro_use] //! extern crate amethyst_config; //! //! use amethyst_config::Element; //! use std::path::Path; //! //! config! { //! struct MyConfig { //! pub amount: i32 = 50, //! } //! } //! //! fn main() { //! let config = MyConfig::default(); //! assert_eq!(config.amount, 50); //! } //! ``` //! //! `Config` is the name of the rust struct that will be generated by the macro. //! It can be anything as long as it would be a valid struct in its context, //! e.g. no other structs by the same name. //! //! The inner fields of `Config` can be summed up as: //! //! ```ignore rust //! name: type = default, //! ``` //! //! The field name will be looked up when attempting to load from a .yml/.yaml //! file. If it is found, then the value will be converted from a YAML type to //! a Rust type and assigned to the field. //! //! If a field is missing from the config file or has a value of a wrong type, //! the Rust field will fall back to the `default` value. //! //! In addition to basic types, any struct created through the `config!` macro //! will automatically implement the [`Element`](trait.Element.html) trait, //! meaning you can nest configuration structs inside each other like so: //! //! ```rust //! # #[macro_use] extern crate amethyst_config; //! # use amethyst_config::Element; //! # use std::path::Path; //! //! config! { //! struct NestedConfig { //! pub some_field: [i64; 3] = [1, 2, 3], //! } //! } //! //! config! { //! struct Config { //! pub nested: NestedConfig = NestedConfig::default(), //! } //! } //! # fn main() { } //! ``` //! //! # External YAML files //! //! In the event that a config file is getting too long, you may define it in //! the YAML file as an "extern" field. For example: //! //! ```yaml //! display: "extern" //! ``` //! //! This works similarly to Rust's module system. It will first search for //! "\\display\\config.yml" in the current context. If it cannot find it, then //! it will look for "\\display.yml". If it cannot find either of these, then //! the value will be defaulted in addition to `display` being overwritten if //! you called `write_file()`. //! //! # Enums //! //! When `config!` is used on an enum type, it automatically implements the //! `Element` trait. However, it does not provide possibilities for data holding //! enums, only simple options list enums. //! //! ```rust //! # #[macro_use] extern crate amethyst_config; //! # use amethyst_config::Element; //! # use std::path::Path; //! config! { //! enum EnumName { //! Option1, //! Option2, //! } //! } //! //! config! { //! struct Config { //! pub field: EnumName = EnumName::Option2, //! } //! } //! //! fn main() { //! let config = Config::default(); //! assert_eq!(config.field, EnumName::Option2); //! } //! ``` //! //! # Documentation and commenting //! //! Normally when constructing a config, you might add a small description as to //! what the fields will be used for and possibly their default values, if they //! have any. //! //! ```rust //! # #[macro_use] //! # extern crate amethyst_config; //! # //! # use amethyst_config::Element; //! # use std::path::Path; //! config! { //! struct Config { //! /// Width and height of the window on initialization. Defaults to //! /// 1024x768. //! pub dimensions: [u16; 2] = [1024, 768], //! } //! } //! # fn main() { } //! ``` //! //! If the macro has problems expanding, then you may want to check whether you //! have the documentation on the line before the field and that you have the //! `pub` identifier before the field name. #![crate_name = "amethyst_config"] #![crate_type = "lib"] #![doc(html_logo_url = "http://tinyurl.com/hgsb45k")] extern crate yaml_rust; #[macro_use] mod definitions; mod yaml; use std::path::Path; pub use definitions::{ConfigMeta, ConfigError}; pub use yaml::{Element, to_string}; pub use yaml_rust::Yaml; config! { struct DisplayConfig { pub title: String = "Amethyst game".to_string(), pub brightness: f64 = 1.0, pub fullscreen: bool = false, pub dimensions: (u16, u16) = (1024, 768), pub min_dimensions: Option<(u16, u16)> = None, pub max_dimensions: Option<(u16, u16)> = None, pub vsync: bool = true, pub multisampling: u16 = 0, pub visibility: bool = true, } } config! { struct LoggingConfig { pub file_path: String = "new_project.log".to_string(), pub output_level: String = "warn".to_string(), pub logging_level: String = "debug".to_string(), } } config! { struct Config { /// Configuration for display and graphics pub display: DisplayConfig = DisplayConfig::default(), /// Configuration for output pub logging: LoggingConfig = LoggingConfig::default(), } }