# Targets _Some helpers to get you started with declarative programming in Rust_ ## Usage This crate defines 3 macros: - `capture!($ident)`: register the base requisite - `target!($ident($args) -> $ty = $expre)`: define a target that builds something from prerequisites with a fixed recipe - `build!($ident: $ty, $builder)`: build a target based on a given state ## Example Let's build a `Dashboard` struct, containing a welcome message for a user. We define the base requisite as a `State` struct, which contains a session identifier. In order to construct the dashboard, we need the actual message and the logged in user. These are defined as two separate, dependent targets. ``` #[macro_use] extern crate targets; use targets::Target; use targets::Builder; pub struct State { logged_in_id: i32, message_of_the_day: String, } pub struct User { id: i32, username: String, } pub struct Dashboard { message: String, } fn main() { // register `state` which is the base requisite capture!(state); // declare a target which depends on `state` target!(fn user(state: State) -> User = { User { id: state.logged_in_id, // you may want to get the user from a database username: "otto".to_string() } }); // declare a target which depends on another target target!(fn message(user: User) -> String = { String::from(format!("Welcome {} (user_id {})", user.username, user.id)) }); // a target can depend on as many other targets target!(fn dashboard(message: String, state: State) -> Dashboard = { Dashboard { message: format!("{} {}", state.message_of_the_day, message), } }); // Let's run our build script, set up the state: let my_state = State { logged_in_id: 8, message_of_the_day: String::from("Good morning!") }; let mut my_builder = Builder::new(Box::new(my_state)); // Build the dashboard: { let my_dashboard = build!(dashboard: Dashboard, my_builder); assert_eq!("Good morning! Welcome otto (user_id 8)", my_dashboard.message); } // Build another target from the same initial state // Since it has already been built as part of the dashboard, it won't rebuild anything { let my_user = build!(user: User, my_builder); assert_eq!("otto", my_user.username); } // Use our dependency graph to build another item let my_state = State { logged_in_id: 12, message_of_the_day: String::from("It's Wednesday!") }; let mut my_builder = Builder::new(Box::new(my_state)); { let my_dashboard = build!(dashboard: Dashboard, my_builder); assert_eq!("It's Wednesday! Welcome otto (user_id 12)", my_dashboard.message); } } ```