136 lines
4.0 KiB
Rust
136 lines
4.0 KiB
Rust
use fathom_function::forms::TableCellValue;
|
|
use fathom_function::tracing;
|
|
use pipeline_application::application::{
|
|
Application, CrossingConfiguration, CrossingKind, FacilityType, SegmentationConfiguration,
|
|
uom::si::f64::Length, uom::si::length::meter,
|
|
};
|
|
use serde::{Deserialize, Serialize};
|
|
use uuid::Uuid;
|
|
|
|
#[fathom_function::function]
|
|
async fn segment(input: Input) -> Result<Output, String> {
|
|
let app = Application::new_from_compile_env(input.org_id, input.project_id).unwrap();
|
|
|
|
for pipeline_id in input.pipeline_id {
|
|
app.segment(pipeline_id, &input.configuration)
|
|
.await
|
|
.map_err(|err| {
|
|
tracing::error!(%pipeline_id, ?err, "Error running segmentation algorithm");
|
|
format!("{err:?}")
|
|
})?;
|
|
}
|
|
|
|
Ok(Output {
|
|
status: "Success".to_owned(),
|
|
})
|
|
}
|
|
|
|
#[derive(Debug, Serialize)]
|
|
struct Output {
|
|
status: String,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
struct Input {
|
|
org_id: Uuid,
|
|
project_id: String,
|
|
pipeline_id: Vec<Uuid>,
|
|
#[serde(flatten)]
|
|
configuration: Configuration,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
struct Configuration {
|
|
facilities: Vec<FacilityType>,
|
|
local_data: Vec<String>,
|
|
crossings: Crossings,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
struct Crossings {
|
|
highway: CrossingRow,
|
|
road: CrossingRow,
|
|
river: CrossingRow,
|
|
railroad: CrossingRow,
|
|
overhead: CrossingRow,
|
|
pipeline: CrossingRow,
|
|
}
|
|
|
|
impl Crossings {
|
|
fn to_crossing_configurations(&self) -> impl Iterator<Item = CrossingConfiguration> {
|
|
[
|
|
self.highway
|
|
.to_crossing_configuration(CrossingKind::Highway),
|
|
self.road.to_crossing_configuration(CrossingKind::Road),
|
|
self.river.to_crossing_configuration(CrossingKind::River),
|
|
self.railroad
|
|
.to_crossing_configuration(CrossingKind::Railroad),
|
|
self.overhead
|
|
.to_crossing_configuration(CrossingKind::Overhead),
|
|
self.pipeline
|
|
.to_crossing_configuration(CrossingKind::Pipeline),
|
|
]
|
|
.into_iter()
|
|
.flatten()
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
struct CrossingRow {
|
|
longer_than: TableCellValue,
|
|
selected: TableCellValue,
|
|
}
|
|
|
|
impl CrossingRow {
|
|
fn to_crossing_configuration(
|
|
&self,
|
|
crossing_kind: CrossingKind,
|
|
) -> Option<CrossingConfiguration> {
|
|
if (&self.selected).try_into().unwrap_or(false) {
|
|
Some(CrossingConfiguration {
|
|
crossing_kind,
|
|
longer_than: Length::new::<meter>(
|
|
(&self.longer_than).try_into().ok().unwrap_or(0.0),
|
|
),
|
|
})
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<&Configuration> for SegmentationConfiguration {
|
|
fn from(value: &Configuration) -> Self {
|
|
let mut config = Self::default_false();
|
|
config = value
|
|
.facilities
|
|
.iter()
|
|
.fold(config, |config, fac| match fac {
|
|
FacilityType::InsulationJoint => config.by_insulation_joints(true),
|
|
FacilityType::Repair => config.by_repairs(true),
|
|
FacilityType::Valve => config.by_valves(true),
|
|
_ => config,
|
|
});
|
|
|
|
config = value.crossings.to_crossing_configurations().fold(
|
|
config,
|
|
SegmentationConfiguration::with_crossing_configuration,
|
|
);
|
|
|
|
value
|
|
.local_data
|
|
.iter()
|
|
.fold(config, |config, loc| 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,
|
|
})
|
|
}
|
|
}
|