use axum::http::HeaderMap; use axum::{routing::post, Router}; use pipeline_application::application::{Application, Env, SegmentationConfiguration}; use pipeline_configuration::facilities::FacilityType; use std::io; use std::net::SocketAddr; use tokio::net::TcpListener; use uuid::Uuid; async fn segment(headers: HeaderMap, body: String) -> String { let env = std::env::vars().collect::>(); let context = Context::from_env().unwrap(); let args = Args::from_body(&body).unwrap(); Application::new(context.env, context.org_id, context.project_id) .unwrap() .segment_all(args) .await .unwrap(); format!("Request headers: {headers:?}, request body: {body}, env: {env:?}") } struct Context { org_id: Uuid, project_id: String, env: Env, } impl Context { fn from_env() -> io::Result { let org_id = std::env::var("ORG_ID") .map_err(io::Error::other)? .parse() .map_err(io::Error::other)?; let project_id = std::env::var("PROJECT_ID").map_err(io::Error::other)?; Ok(Self { org_id, project_id, env: Self::get_env(), }) } fn get_env() -> Env { match std::env::var("ENV") { Ok(env) if env == "stg" || env == "staging" => Env::Staging, _ => Env::Dev, } } } #[tokio::main] async fn main() { let router = Router::new().route("/", post(segment)); let addr = SocketAddr::from(([0, 0, 0, 0], 8080)); let tcp = TcpListener::bind(&addr).await.unwrap(); println!("Ready and listening on {}", addr); axum::serve(tcp, router).await.unwrap(); } #[derive(Debug, serde::Deserialize)] struct Args { facilities: Vec, local_data: Vec, } impl From for SegmentationConfiguration { fn from(value: Args) -> Self { let mut config = Self::default(); for fac in value.facilities { config = match fac { FacilityType::InsulationJoint => config.by_insulation_joints(true), FacilityType::Repair => config.by_repairs(true), FacilityType::Valve => config.by_valves(true), _ => config, }; } // TODO: add crossing configuration for loc in value.local_data { config = match loc.as_str() { "material_grade" => config.by_material_grade(true), "coating_type" => config.by_coating_type(true), "design_factor" => config.by_design_factor(true), "high_consequence_area" => config.by_high_consequence_area(true), "unusual_sensitive_area" => config.by_unusual_sensitive_area(true), "joint_type" => config.by_joint_type(true), "soil_type" => config.by_soil_type(true), "soil_ph" => config.by_soil_ph(true), _ => config, } } config } } impl Args { fn from_body(body: &str) -> serde_json::Result { let value: String = serde_json::from_str(body)?; serde_json::from_str(&value) } } #[cfg(test)] mod tests { use super::*; const INPUT: &str = "\"{\\\"facilities\\\": [\\\"repair\\\"], \\\"formData\\\": {\\\"facilities\\\": [\\\"repairs\\\"], \\\"localProperties\\\": [\\\"material_grade\\\", \\\"coating_type\\\", \\\"soil_type\\\", \\\"soil_ph\\\"]}, \\\"input\\\": null, \\\"local_data\\\": [\\\"material_grade\\\", \\\"coating_type\\\", \\\"soil_type\\\", \\\"soil_ph\\\"]}\""; #[test] fn test() { let env = std::env::vars().collect::>(); println!("body: {}, env: {env:?}", INPUT); let args = Args::from_body(INPUT); dbg!(args).unwrap(); } }