Skip to main content

verificar/transpiler/
mod.rs

1//! Transpiler integration
2//!
3//! This module provides the trait definition for transpilers and
4//! integration with PAIML transpiler projects.
5//!
6//! # Supported Transpilers
7//!
8//! - **depyler**: Python → Rust
9//! - **bashrs**: Bash → Safe Shell
10//! - **ruchy**: Ruchy (standalone language)
11//! - **decy**: C → Rust
12
13mod ml_oracle;
14mod oracle;
15
16pub use ml_oracle::{
17    BaselinePredictor, BugPredictor, CodeFeatures, ComplexityPredictor, TestPrioritizer,
18};
19pub use oracle::{TranspilerOracle, TranspilerVerdict, TranspilerVerification, VerificationStats};
20
21use crate::grammar::Grammar;
22use crate::{Language, Result};
23
24/// Trait implemented by each transpiler
25///
26/// From spec Section 3.2: Contract enforcement via Rust type system.
27pub trait Transpiler: Send + Sync {
28    /// Source language identifier
29    fn source_language(&self) -> Language;
30
31    /// Target language identifier
32    fn target_language(&self) -> Language;
33
34    /// Transpile source to target
35    ///
36    /// # Errors
37    ///
38    /// Returns an error if transpilation fails
39    fn transpile(&self, source: &str) -> Result<String>;
40
41    /// Grammar for source language
42    fn grammar(&self) -> &dyn Grammar;
43
44    /// Get transpiler version
45    fn version(&self) -> &str;
46}
47
48/// Configuration for transpiler testing
49#[derive(Debug, Clone)]
50pub struct TranspilerConfig {
51    /// Name of the transpiler
52    pub name: String,
53    /// Source language
54    pub source: Language,
55    /// Target language
56    pub target: Language,
57    /// Enable strict mode
58    pub strict: bool,
59}
60
61impl TranspilerConfig {
62    /// Configuration for depyler (Python → Rust)
63    #[must_use]
64    pub fn depyler() -> Self {
65        Self {
66            name: "depyler".to_string(),
67            source: Language::Python,
68            target: Language::Rust,
69            strict: true,
70        }
71    }
72
73    /// Configuration for bashrs (Bash → Safe Shell)
74    #[must_use]
75    pub fn bashrs() -> Self {
76        Self {
77            name: "bashrs".to_string(),
78            source: Language::Bash,
79            target: Language::Rust,
80            strict: true,
81        }
82    }
83
84    /// Configuration for ruchy (standalone Ruchy language)
85    #[must_use]
86    pub fn ruchy() -> Self {
87        Self {
88            name: "ruchy".to_string(),
89            source: Language::Ruchy,
90            target: Language::Rust,
91            strict: true,
92        }
93    }
94
95    /// Configuration for decy (C → Rust)
96    #[must_use]
97    pub fn decy() -> Self {
98        Self {
99            name: "decy".to_string(),
100            source: Language::C,
101            target: Language::Rust,
102            strict: true,
103        }
104    }
105}
106
107#[cfg(test)]
108mod tests {
109    use super::*;
110
111    #[test]
112    fn test_depyler_config() {
113        let config = TranspilerConfig::depyler();
114        assert_eq!(config.name, "depyler");
115        assert_eq!(config.source, Language::Python);
116        assert_eq!(config.target, Language::Rust);
117        assert!(config.strict);
118    }
119
120    #[test]
121    fn test_bashrs_config() {
122        let config = TranspilerConfig::bashrs();
123        assert_eq!(config.name, "bashrs");
124        assert_eq!(config.source, Language::Bash);
125        assert_eq!(config.target, Language::Rust);
126        assert!(config.strict);
127    }
128
129    #[test]
130    fn test_ruchy_config() {
131        let config = TranspilerConfig::ruchy();
132        assert_eq!(config.name, "ruchy");
133        assert_eq!(config.source, Language::Ruchy);
134        assert_eq!(config.target, Language::Rust);
135        assert!(config.strict);
136    }
137
138    #[test]
139    fn test_decy_config() {
140        let config = TranspilerConfig::decy();
141        assert_eq!(config.name, "decy");
142        assert_eq!(config.source, Language::C);
143        assert_eq!(config.target, Language::Rust);
144        assert!(config.strict);
145    }
146
147    #[test]
148    fn test_transpiler_config_debug() {
149        let config = TranspilerConfig::depyler();
150        let debug = format!("{:?}", config);
151        assert!(debug.contains("TranspilerConfig"));
152        assert!(debug.contains("depyler"));
153    }
154
155    #[test]
156    fn test_transpiler_config_clone() {
157        let config = TranspilerConfig::depyler();
158        let cloned = config.clone();
159        assert_eq!(cloned.name, config.name);
160        assert_eq!(cloned.source, config.source);
161        assert_eq!(cloned.target, config.target);
162    }
163}