pipa_core/engine/contracts/
meta.rs1use crate::contracts::load_contract_for_file; use crate::engine::log_action; use glob; use std::path::Path;
7
8pub struct ContractList {
10 pub contracts: Vec<String>, }
12
13pub struct ContractInfo {
15 pub name: String, pub version: String, pub exists: bool, }
19
20pub struct ContractValidation {
22 pub valid: bool, pub error: Option<String>, }
25
26pub fn list_contracts() -> Result<(ContractList, String), String> {
29 let contracts: Vec<String> = match glob::glob("contracts/*.toml") {
30 Ok(paths) => paths
31 .filter_map(Result::ok)
32 .filter_map(|p| {
33 p.file_stem()
34 .and_then(|s| s.to_str())
35 .map(|s| s.to_string())
36 })
37 .collect(),
38 Err(_) => return Err("Failed to read contracts directory".to_string()),
39 };
40
41 let message = log_action("contracts_listed", None, None, None, None);
42 Ok((ContractList { contracts }, message))
43}
44
45pub fn get_contract(name: &str) -> (ContractInfo, String) {
48 let contract_path = format!("contracts/{}.toml", name);
49
50 if !Path::new(&contract_path).exists() {
51 let message = log_action(
52 "contract_retrieved",
53 Some("exists=false"),
54 Some(name),
55 None,
56 None,
57 );
58 return (
59 ContractInfo {
60 name: name.to_string(),
61 version: "".to_string(),
62 exists: false,
63 },
64 message,
65 );
66 }
67
68 let contract = load_contract_for_file(Path::new(&contract_path));
69 let message = log_action(
70 "contract_retrieved",
71 Some("exists=true"),
72 Some(&contract.contract.name),
73 Some(&contract.contract.version),
74 None,
75 );
76 (
77 ContractInfo {
78 name: contract.contract.name,
79 version: contract.contract.version,
80 exists: true,
81 },
82 message,
83 )
84}
85
86pub fn validate_contract(name: &str) -> (ContractValidation, String) {
90 let contract_path = format!("contracts/{}.toml", name);
91
92 if !Path::new(&contract_path).exists() {
93 let message = log_action(
94 "contract_validated",
95 Some("error=Contract not found"),
96 Some(name),
97 None,
98 None,
99 );
100 return (
101 ContractValidation {
102 valid: false,
103 error: Some("Contract not found".to_string()),
104 },
105 message,
106 );
107 }
108
109 match std::panic::catch_unwind(|| load_contract_for_file(Path::new(&contract_path))) {
110 Ok(contract) => {
111 let message = log_action(
112 "contract_validated",
113 Some("valid=true"),
114 Some(&contract.contract.name),
115 Some(&contract.contract.version),
116 None,
117 );
118 (
119 ContractValidation {
120 valid: true,
121 error: None,
122 },
123 message,
124 )
125 }
126 Err(_) => {
127 let message = log_action(
128 "contract_validated",
129 Some("error=Contract failed to parse"),
130 Some(name),
131 None,
132 None,
133 );
134 (
135 ContractValidation {
136 valid: false,
137 error: Some("Contract failed to parse".to_string()),
138 },
139 message,
140 )
141 }
142 }
143}