refactor: add result type for Program (#8179)

This commit is contained in:
Prajjwal Kumar
2025-06-12 16:07:36 +05:30
committed by GitHub
parent 4318c934dd
commit 261818f215
2 changed files with 79 additions and 45 deletions

View File

@ -1,6 +1,9 @@
use std::collections::{HashMap, HashSet};
use api_models::routing as api_routing;
use api_models::{
routing as api_routing,
routing::{ConnectorSelection, RoutableConnectorChoice},
};
use async_trait::async_trait;
use common_utils::id_type;
use diesel_models::{enums, routing_algorithm};
@ -712,48 +715,70 @@ impl From<RoutingAlgorithmRecord> for routing_algorithm::RoutingProfileMetadata
}
}
}
use api_models::routing::{ConnectorSelection, RoutableConnectorChoice};
impl From<ast::Program<ConnectorSelection>> for Program {
fn from(p: ast::Program<ConnectorSelection>) -> Self {
Self {
impl TryFrom<ast::Program<ConnectorSelection>> for Program {
type Error = error_stack::Report<errors::RoutingError>;
fn try_from(p: ast::Program<ConnectorSelection>) -> Result<Self, Self::Error> {
let rules = p
.rules
.into_iter()
.map(convert_rule)
.collect::<Result<Vec<_>, _>>()?;
Ok(Self {
globals: HashMap::new(),
default_selection: convert_output(p.default_selection),
rules: p.rules.into_iter().map(convert_rule).collect(),
rules,
metadata: Some(p.metadata),
}
})
}
}
fn convert_rule(rule: ast::Rule<ConnectorSelection>) -> Rule {
fn convert_rule(rule: ast::Rule<ConnectorSelection>) -> RoutingResult<Rule> {
let routing_type = match &rule.connector_selection {
ConnectorSelection::Priority(_) => RoutingType::Priority,
ConnectorSelection::VolumeSplit(_) => RoutingType::VolumeSplit,
};
Rule {
Ok(Rule {
name: rule.name,
routing_type,
output: convert_output(rule.connector_selection),
statements: rule.statements.into_iter().map(convert_if_stmt).collect(),
}
statements: rule
.statements
.into_iter()
.map(convert_if_stmt)
.collect::<RoutingResult<Vec<IfStatement>>>()?,
})
}
fn convert_if_stmt(stmt: ast::IfStatement) -> IfStatement {
IfStatement {
condition: stmt.condition.into_iter().map(convert_comparison).collect(),
fn convert_if_stmt(stmt: ast::IfStatement) -> RoutingResult<IfStatement> {
Ok(IfStatement {
condition: stmt
.condition
.into_iter()
.map(convert_comparison)
.collect::<RoutingResult<Vec<Comparison>>>()?,
nested: stmt
.nested
.map(|v| v.into_iter().map(convert_if_stmt).collect()),
}
.map(|v| {
v.into_iter()
.map(convert_if_stmt)
.collect::<RoutingResult<Vec<IfStatement>>>()
})
.transpose()?,
})
}
fn convert_comparison(c: ast::Comparison) -> Comparison {
Comparison {
fn convert_comparison(c: ast::Comparison) -> RoutingResult<Comparison> {
Ok(Comparison {
lhs: c.lhs,
comparison: convert_comparison_type(c.comparison),
value: convert_value(c.value),
value: convert_value(c.value)?,
metadata: c.metadata,
}
})
}
fn convert_comparison_type(ct: ast::ComparisonType) -> ComparisonType {
@ -767,18 +792,21 @@ fn convert_comparison_type(ct: ast::ComparisonType) -> ComparisonType {
}
}
#[allow(clippy::unimplemented)]
fn convert_value(v: ast::ValueType) -> ValueType {
fn convert_value(v: ast::ValueType) -> RoutingResult<ValueType> {
use ast::ValueType::*;
match v {
Number(n) => ValueType::Number(n.get_amount_as_i64().try_into().unwrap_or_default()),
EnumVariant(e) => ValueType::EnumVariant(e),
MetadataVariant(m) => ValueType::MetadataVariant(MetadataValue {
Number(n) => Ok(ValueType::Number(
n.get_amount_as_i64().try_into().unwrap_or_default(),
)),
EnumVariant(e) => Ok(ValueType::EnumVariant(e)),
MetadataVariant(m) => Ok(ValueType::MetadataVariant(MetadataValue {
key: m.key,
value: m.value,
}),
StrValue(s) => ValueType::StrValue(s),
_ => unimplemented!(), // GlobalRef(r) => ValueType::GlobalRef(r),
})),
StrValue(s) => Ok(ValueType::StrValue(s)),
_ => Err(error_stack::Report::new(
errors::RoutingError::InvalidRoutingAlgorithmStructure,
)),
}
}

View File

@ -342,7 +342,8 @@ pub async fn create_routing_algorithm_under_profile(
let mut decision_engine_routing_id: Option<String> = None;
if let Some(EuclidAlgorithm::Advanced(program)) = request.algorithm.clone() {
let internal_program: Program = program.into();
match program.try_into() {
Ok(internal_program) => {
let routing_rule = RoutingRule {
name: name.clone(),
description: Some(description.clone()),
@ -358,11 +359,16 @@ pub async fn create_routing_algorithm_under_profile(
.await
.map_err(|e| {
// errors are ignored as this is just for diff checking as of now (optional flow).
logger::error!(decision_engine_error=?e, "decision_engine_euclid");
logger::debug!(decision_engine_request=?routing_rule, "decision_engine_euclid");
logger::error!(decision_engine_error=?e,decision_engine_euclid_request=?routing_rule, "failed to create rule in decision_engine");
})
.ok();
}
Err(e) => {
// errors are ignored as this is just for diff checking as of now (optional flow).
logger::error!(decision_engine_error=?e, "decision_engine_euclid");
}
};
}
if decision_engine_routing_id.is_some() {
logger::info!(routing_flow=?"create_euclid_routing_algorithm", is_equal=?"true", "decision_engine_euclid");