aprender_contracts_cli/commands/
tla.rs1use std::path::Path;
2
3use provable_contracts::graph::dependency_graph;
4use provable_contracts::schema::{parse_contract, Contract};
5use provable_contracts::tla_gen::generate_tla_module;
6
7pub fn run(contract_dir: &Path) -> Result<(), Box<dyn std::error::Error>> {
8 let mut contracts: Vec<(String, Contract)> = Vec::new();
9
10 let entries = std::fs::read_dir(contract_dir)?;
11 for entry in entries {
12 let entry = entry?;
13 let path = entry.path();
14 if path.extension().and_then(|e| e.to_str()) == Some("yaml") {
15 let stem = path
16 .file_stem()
17 .and_then(|s| s.to_str())
18 .unwrap_or("unknown")
19 .to_string();
20 match parse_contract(&path) {
21 Ok(c) => contracts.push((stem, c)),
22 Err(e) => {
23 eprintln!("warning: skipping {}: {e}", path.display());
24 }
25 }
26 }
27 }
28
29 contracts.sort_by(|a, b| a.0.cmp(&b.0));
30
31 let refs: Vec<(String, &Contract)> = contracts.iter().map(|(s, c)| (s.clone(), c)).collect();
32 let graph = dependency_graph(&refs);
33
34 let module_name = contract_dir
35 .file_name()
36 .and_then(|s| s.to_str())
37 .unwrap_or("Contracts");
38 let module_name = module_name
39 .chars()
40 .filter(|c| c.is_alphanumeric())
41 .collect::<String>();
42 let module_name = if module_name.is_empty() {
43 "Contracts".to_string()
44 } else {
45 let mut chars = module_name.chars();
47 match chars.next() {
48 None => "Contracts".to_string(),
49 Some(first) => first.to_uppercase().collect::<String>() + chars.as_str(),
50 }
51 };
52
53 let output = generate_tla_module(&module_name, &refs, &graph);
54 print!("{output}");
55
56 Ok(())
57}