use feattle::*; use std::collections::BTreeMap; use std::env; use std::error::Error; use std::future::IntoFuture; use std::sync::Arc; use tokio::net::TcpListener; use tokio::time::Duration; use uuid::Uuid; // Declare the struct that will gather all the feature toggles. // Each field is turned into a method and allows a default value to be provided. feattles! { struct SimulationToggles { /// Activates extruding the mesh terrain, usually in the minor inertia axis. extrude_mesh_terrain: bool, /// The domestic module being always present, requires some balancing. balance_domestic_coefficients: u8 = 17, /// When to pause the bucolic routine to wonder about future capital availability calculate_money_supply: CalculateMoneySupply = CalculateMoneySupply::EveryNowAndThen, /// Some entities will respond to some links only map_influence_attributes: BTreeMap = default_map_influence_attributes(), /// A boolean, or not, for more chaos. iterate_chaos_array: Option, } } // Declare the enums that can be used as types for feattles feattle_enum! { enum CalculateMoneySupply { Always, EveryNowAndThen, MostlyAvoid, } } feattle_enum! { #[allow(clippy::enum_variant_names)] enum MapInfluenceAttributes { FriendsOnly, FamilyOnly, PetsOnly, ImaginaryDragonsOnly, } } /// Provide the default value for `map_influence_attributes` fn default_map_influence_attributes() -> BTreeMap { let mut value = BTreeMap::new(); value.insert( Uuid::parse_str("4d57d909-c87d-4e89-b40d-236d23b59e82").unwrap(), MapInfluenceAttributes::FamilyOnly, ); value.insert( Uuid::parse_str("aa8d90e6-8745-4c89-a48b-b8499347fe31").unwrap(), MapInfluenceAttributes::ImaginaryDragonsOnly, ); value } #[tokio::main] async fn main() -> Result<(), Box> { // Load configurations from `.env` file, please copy this template and fill it in: // ``` // AWS_ACCESS_KEY_ID= // AWS_SECRET_ACCESS_KEY= // AWS_REGION= // S3_BUCKET= // S3_KEY_PREFIX= // ADMIN_PANEL_LABEL= // ``` dotenv::dotenv()?; let s3_bucket = env::var("S3_BUCKET").unwrap(); let s3_key_prefix = env::var("S3_KEY_PREFIX").unwrap(); let admin_panel_label = env::var("ADMIN_PANEL_LABEL").unwrap(); env_logger::init(); // Create the S3 persistence let config = aws_config::load_from_env().await; let s3_storage = Arc::new(S3::new(&config, s3_bucket, s3_key_prefix)); // Create the instance let features = Arc::new(SimulationToggles::new(s3_storage)); // Sync in the background BackgroundSync::new(&features).start().await; // Create the admin panel let panel = Arc::new(AdminPanel::new(features.clone(), admin_panel_label)); // Serve the admin panel with `warp` tokio::spawn(run_warp_server(panel.clone(), ([127, 0, 0, 1], 3030))); // Serve the admin panel with `axum` let router = axum_router(panel); let listener = TcpListener::bind(("127.0.0.1", 3031)).await?; tokio::spawn(axum::serve(listener, router.into_make_service()).into_future()); println!("Admin UI available in http://127.0.0.1:3030"); loop { println!("--- Values are ---"); println!( "extrude_mesh_terrain = {:?}", features.extrude_mesh_terrain() ); println!( "balance_domestic_coefficients = {:?}", features.balance_domestic_coefficients() ); println!( "calculate_money_supply = {:?}", features.calculate_money_supply() ); println!( "map_influence_attributes = {:?}", features.map_influence_attributes() ); println!("iterate_chaos_array = {:?}", features.iterate_chaos_array()); tokio::time::sleep(Duration::from_secs(5)).await; } }