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
//! This crate aims to help with reading configuration of application from files, //! environment variables and command line arguments, merging it together and //! validating. It auto-generates most of the code for you based on configuration (heh) //! file. It creates a struct for you, which contains all the parsed and validated //! fields, so you can access the information quickly easily and idiomatically. //! //! This is currently only a facade for the dependencies, the core of the crate is in //! `configure_me_codegen` crate. //! //! **Important:** In order to use this crate, you need to create a build script using //! `configure_me_codegen` to generate the code that will use this crate! See the example. //! //! Example //! ------- //! //! Let's say, your application needs these parametrs to run: //! //! * Port - this is mandatory //! * IP address to bind to - defaults to 0.0.0.0 //! * Path to TLS certificate - optional, the server will be unsecure if not given //! //! First create `config_spec.toml` configuration file specifying all the parameters: //! //! ```toml //! [[param]] //! name = "port" //! type = "u16" //! optional = false //! # This text will be used in the documentation (help etc) //! # It's not mandatory, but your progam will be ugly without it. //! doc = "Port to listen on." //! //! [[param]] //! name = "bind_addr" //! # Yes, this works and you can use your own T: Deserialize + ParseArg as well! //! type = "::std::net::Ipv4Addr" //! default = "::std::net::Ipv4Addr::new(0, 0, 0, 0)" # Rust expression that creates the value //! doc = "IP address to bind to." //! //! [[param]] //! name = "tls_cert" //! type = "::std::path::PathBuf" //! doc = "Path to the TLS certificate. The connections will be unsecure if it isn't provided." //! # optional = true is the default, no need to add it here //! # If the type is optional, it will be represented as Option<T> //! # e.g. Option<::std::path::PathBuf> in this case. //! ``` //! //! Then, create a simple build script: //! //! ```rust,ignore //! extern crate configure_me; //! //! fn main() { //! configure_me::build_script_auto().unwrap_or_exit(); //! } //! ``` //! //! Add dependencies to `Cargo.toml`: //! //! ```toml //! [packge] //! # ... //! build = "build.rs" //! //! # This tells auto build script and other tools where to look for your specificcation //! [package.metadata.configure_me] //! spec = "config_spec.toml" //! //! [dependencies] //! configure_me = "0.3" //! //! [build-dependencies] //! configure_me_codegen = "0.3" //! ``` //! //! And finally add appropriate incantiations into `src/main.rs`: //! //! ```rust,ignore //! #[macro_use] //! extern crate configure_me; //! //! include_config!(); //! //! fn main() { //! // This will read configuration from "/etc/my_awesome_server/server.conf" file and //! // the command-line arguments. //! let (server_config, _remaining_args) = Config::including_optional_config_files(&["/etc/my_awesome_server/server.conf]").unwrap_or_exit(); //! //! // Your code here //! // E.g.: //! let listener = std::net::TcpListener::bind((server_config.bind_addr, server_config.port)).expect("Failed to bind socket"); //! } //! ``` pub extern crate serde; pub extern crate toml; pub extern crate parse_arg; #[allow(unused_imports)] #[macro_use] extern crate serde_derive; #[doc(hidden)] pub use serde_derive::*; #[macro_export] macro_rules! include_config { () => { mod config { #![allow(unused)] include!(concat!(env!("OUT_DIR"), "/configure_me_config.rs")); } use config::prelude::*; }; ($binary:literal) => { mod config { #![allow(unused)] include!(concat!(env!("OUT_DIR"), "/", $binary, "_configure_me_config.rs")); } use config::prelude::*; }; }