Skip to content

Commit e5746cd

Browse files
committed
feat: implement field-level configuration support for MT sample generation
• Add comprehensive field-level configuration for amount ranges and currency • Implement message-level and field-level sample_with_config support • Enhance SwiftMTMessage integration with proper configuration handling • Add MT Sample Generator UI with simplified configuration interface • Modularize main.rs into separate engine, handlers, types, and sample_generator modules • Update to SwiftMTMessage v2.3.6 with enhanced realistic data generation • Add support for Option<T> and Vec<T> type configurations • Implement proper field tag to configuration mapping (32A, 33B, 71F, 71G, 32B) • Add comprehensive error handling and validation for field configurations • Enhance web UI with improved layout and user experience
1 parent 3de47c3 commit e5746cd

17 files changed

+2499
-2183
lines changed

Cargo.lock

Lines changed: 67 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ quick-xml = { version = "0.37", features = ["serialize"] } # For XML serializat
1818

1919
dataflow-rs = "0.1.28"
2020
# dataflow-rs = { path = "../dataflow-rs" }
21-
swift-mt-message = { version = "2.2.16" }
21+
swift-mt-message = { version = "2.3.6" }
2222
# swift-mt-message = { path = "../SwiftMTMessage/swift-mt-message" }
2323
mx-message = "0.1.9"
2424

@@ -28,5 +28,6 @@ tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }
2828
tracing-log = "0.2"
2929
tracing-appender = "0.2"
3030
regex = "1.0"
31+
rand = "0.8"
3132
chrono = { version = "0.4", features = ["serde"] }
3233
serde-xml-rs = "0.8.1"

RELEASE-NOTES.md

Lines changed: 0 additions & 632 deletions
This file was deleted.

src/engine.rs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
use dataflow_rs::{Engine, Workflow};
2+
use serde_json::Value;
3+
use std::fs;
4+
use std::path::Path;
5+
use std::sync::Arc;
6+
use tokio::sync::Mutex;
7+
use tracing::{info, warn};
8+
9+
use crate::parse_mt::ParseMT;
10+
use crate::parse_mx::ParseMX;
11+
use crate::publish_mt::PublishMT;
12+
use crate::publish_mx::PublishMX;
13+
use crate::types::AppState;
14+
15+
pub async fn initialize_engines() -> AppState {
16+
info!("🔧 Initializing Forward and Reverse Engines");
17+
18+
let forward_engine = initialize_forward_engine()
19+
.await
20+
.expect("Failed to initialize forward engine");
21+
22+
let reverse_engine = initialize_reverse_engine()
23+
.await
24+
.expect("Failed to initialize reverse engine");
25+
26+
info!("✅ Both engines initialized successfully");
27+
28+
AppState {
29+
forward_engine: Arc::new(Mutex::new(forward_engine)),
30+
reverse_engine: Arc::new(Mutex::new(reverse_engine)),
31+
}
32+
}
33+
34+
async fn initialize_forward_engine() -> Result<Engine, Box<dyn std::error::Error>> {
35+
info!("🔄 Setting up Forward Engine (MT → MX)");
36+
37+
let mut engine = Engine::new();
38+
39+
// Register MT-specific functions for forward transformation
40+
engine.register_task_function("ParseMT".to_string(), Box::new(ParseMT));
41+
engine.register_task_function("PublishMX".to_string(), Box::new(PublishMX));
42+
43+
// Load forward workflows
44+
load_workflows_for_engine(&mut engine, "workflows/forward").await?;
45+
46+
info!("✅ Forward Engine (MT → MX) ready");
47+
Ok(engine)
48+
}
49+
50+
async fn initialize_reverse_engine() -> Result<Engine, Box<dyn std::error::Error>> {
51+
info!("🔄 Setting up Reverse Engine (MX → MT)");
52+
53+
let mut engine = Engine::new();
54+
55+
// Register MX-specific functions for reverse transformation
56+
engine.register_task_function("ParseMX".to_string(), Box::new(ParseMX));
57+
engine.register_task_function("PublishMT".to_string(), Box::new(PublishMT));
58+
59+
// Load reverse workflows
60+
load_workflows_for_engine(&mut engine, "workflows/reverse").await?;
61+
62+
info!("✅ Reverse Engine (MX → MT) ready");
63+
Ok(engine)
64+
}
65+
66+
async fn load_workflows_for_engine(
67+
engine: &mut Engine,
68+
workflow_dir: &str,
69+
) -> Result<(), Box<dyn std::error::Error>> {
70+
info!("📁 Loading workflows from {}", workflow_dir);
71+
72+
let index_path = format!("{workflow_dir}/index.json");
73+
if !Path::new(&index_path).exists() {
74+
warn!(
75+
"No index.json found in {}, skipping workflow loading",
76+
workflow_dir
77+
);
78+
return Ok(());
79+
}
80+
81+
let index_content = fs::read_to_string(&index_path)?;
82+
let index: Value = serde_json::from_str(&index_content)?;
83+
84+
if let Some(workflows) = index.get("workflows").and_then(|w| w.as_array()) {
85+
for workflow_entry in workflows {
86+
if let Some(path) = workflow_entry.get("path").and_then(|p| p.as_str()) {
87+
let full_path = format!("{workflow_dir}/{path}");
88+
if Path::new(&full_path).exists() {
89+
let workflow_content = fs::read_to_string(&full_path)?;
90+
let workflow: Workflow = serde_json::from_str(&workflow_content)?;
91+
92+
engine.add_workflow(&workflow);
93+
94+
info!("📄 Loaded workflow: {}", path);
95+
} else {
96+
warn!("Workflow file not found: {}", full_path);
97+
}
98+
}
99+
}
100+
}
101+
102+
Ok(())
103+
}

0 commit comments

Comments
 (0)