954df58f77bc41828aacf596c3a.../src/main.rs
2025-06-11 14:32:05 +00:00

192 lines
5.5 KiB
Rust

use fathom_function::{
chrono::NaiveDate,
forms::{TableCellValue, deserialize_date},
tracing,
};
use pipeline_application::application::{
Application, DimensionClass, InlineInspection, InspectionType, ReportType,
Tolerance as ApplicationTolerance, ToleranceAdjustment, ToolTolerances,
uom::si::{f64::Length, length::millimeter},
};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[fathom_function::function]
async fn ili_creation(input: Input) -> Result<Output, String> {
let reports_details = input.report_details;
let tolerances = input.tolerances;
let app = Application::new_from_compile_env(input.org_id, input.project_id).unwrap();
for (pipeline_id, file_details) in input.pipeline_id.into_iter().zip(input.file_details) {
app.process_ili_report(
pipeline_id,
file_details.file_id,
&tolerances,
&reports_details,
)
.await
.map_err(|err| {
tracing::error!(%pipeline_id, ?err, "Error running ili calculations");
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>,
file_details: Vec<FileDetails>,
#[serde(flatten)]
report_details: InspectionReportDetails,
#[serde(flatten)]
tolerances: CombineTolerances,
}
#[derive(Debug, Deserialize)]
struct CombineTolerances {
haz_tolerances: Tolerances<HazTolerance>,
pipebody_tolerances: Tolerances<Tolerance>,
}
#[derive(Debug, Deserialize)]
struct Tolerances<T> {
general: T,
pitting: T,
axial_grooving: T,
circumferential_grooving: T,
pinhole: T,
axial_slotting: T,
circumferential_slotting: T,
}
#[derive(Debug, Deserialize)]
struct Tolerance {
depth: TableCellValue,
length: TableCellValue,
width: TableCellValue,
}
#[derive(Debug, Deserialize)]
struct HazTolerance {
sensitivity: TableCellValue,
#[serde(flatten)]
tolerance: Tolerance,
}
impl Tolerance {
fn to_tolerance(&self, haz_tolerances: &HazTolerance) -> Option<ApplicationTolerance> {
Some(ApplicationTolerance::new(
Option::<f64>::try_from(&haz_tolerances.sensitivity).ok()??,
Option::<ToleranceAdjustment>::from(&haz_tolerances.tolerance)?,
Option::<ToleranceAdjustment>::from(self)?,
))
}
}
#[derive(Debug, Deserialize)]
struct InspectionReportDetails {
#[serde(deserialize_with = "deserialize_date")]
date: NaiveDate,
vendor_name: String,
report_type: ReportType,
/// The inspection type and technology used.
inspection_type: InspectionType,
}
impl From<&CombineTolerances> for ToolTolerances {
fn from(value: &CombineTolerances) -> Self {
[
(
DimensionClass::General,
value
.pipebody_tolerances
.general
.to_tolerance(&value.haz_tolerances.general),
),
(
DimensionClass::Pitting,
value
.pipebody_tolerances
.pitting
.to_tolerance(&value.haz_tolerances.pitting),
),
(
DimensionClass::AxialGrooving,
value
.pipebody_tolerances
.axial_grooving
.to_tolerance(&value.haz_tolerances.axial_grooving),
),
(
DimensionClass::CircumferentialGrooving,
value
.pipebody_tolerances
.circumferential_grooving
.to_tolerance(&value.haz_tolerances.circumferential_grooving),
),
(
DimensionClass::Pinhole,
value
.pipebody_tolerances
.pinhole
.to_tolerance(&value.haz_tolerances.pinhole),
),
(
DimensionClass::AxialSlotting,
value
.pipebody_tolerances
.axial_slotting
.to_tolerance(&value.haz_tolerances.axial_slotting),
),
(
DimensionClass::CircumferentialSlotting,
value
.pipebody_tolerances
.circumferential_slotting
.to_tolerance(&value.haz_tolerances.circumferential_slotting),
),
]
.into_iter()
.filter_map(|(dc, tol)| tol.map(|tol| (dc, tol)))
.collect()
}
}
impl From<&Tolerance> for Option<ToleranceAdjustment> {
fn from(value: &Tolerance) -> Self {
Some(ToleranceAdjustment {
depth: Option::<f64>::try_from(&value.depth).ok()??,
width: Length::new::<millimeter>(Option::<f64>::try_from(&value.width).ok()??),
length: Length::new::<millimeter>(Option::<f64>::try_from(&value.length).ok()??),
})
}
}
impl From<&InspectionReportDetails> for InlineInspection {
fn from(value: &InspectionReportDetails) -> Self {
Self {
date: value.date,
vendor_name: value.vendor_name.to_owned(),
report_type: value.report_type,
inspection_type: value.inspection_type,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct FileDetails {
pub file_id: Uuid,
pub revision_id: Uuid,
}