Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/athena/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,27 @@ pub enum AthenaError {
ValidationError(String),

#[error("Template error: {0}")]
#[allow(dead_code)]
TemplateError(String),
}

impl AthenaError {
#[allow(dead_code)]
pub fn parse_error<T: Into<String>>(msg: T) -> Self {
AthenaError::ParseError(msg.into())
}

#[allow(dead_code)]
pub fn config_error<T: Into<String>>(msg: T) -> Self {
AthenaError::ConfigError(msg.into())
}

#[allow(dead_code)]
pub fn validation_error<T: Into<String>>(msg: T) -> Self {
AthenaError::ValidationError(msg.into())
}

#[allow(dead_code)]
pub fn template_error<T: Into<String>>(msg: T) -> Self {
AthenaError::TemplateError(msg.into())
}
Expand Down
2 changes: 1 addition & 1 deletion src/athena/generator/compose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub fn generate_docker_compose(athena_file: &AthenaFile) -> AthenaResult<String>

// Generate optimized YAML
let yaml = serde_yaml::to_string(&compose)
.map_err(|e| AthenaError::YamlError(e))?;
.map_err(AthenaError::YamlError)?;

// Improve formatting for better readability
let formatted_yaml = improve_yaml_formatting(yaml);
Expand Down
9 changes: 9 additions & 0 deletions src/athena/generator/defaults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,37 @@ use crate::athena::parser::ast::*;

/// Default Docker Compose configurations based on service patterns and Docker standards
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct ServiceDefaults {
pub restart_policy: RestartPolicy,
pub health_check_interval: String,
pub health_check_timeout: String,
pub health_check_retries: u32,
pub health_check_start_period: String,
#[allow(dead_code)]
pub network_mode: NetworkMode,
pub pull_policy: PullPolicy,
}

#[derive(Debug, Clone)]
#[allow(dead_code)]
pub enum NetworkMode {
Bridge,
#[allow(dead_code)]
Host,
#[allow(dead_code)]
None,
#[allow(dead_code)]
Custom(String),
}

#[derive(Debug, Clone)]
#[allow(dead_code)]
pub enum PullPolicy {
#[allow(dead_code)]
Always,
Missing,
#[allow(dead_code)]
Never,
}

Expand Down
15 changes: 3 additions & 12 deletions src/athena/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,14 @@ pub mod parser;
pub mod generator;

pub use error::{AthenaError, AthenaResult};
pub use parser::{parse_athena_file, AthenaFile, Service};
pub use parser::parse_athena_file;
pub use generator::generate_docker_compose;

/// Configuration for Athena operations
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Default)]
#[allow(dead_code)]
pub struct AthenaConfig {
pub output_file: Option<String>,
pub validate_only: bool,
pub verbose: bool,
}

impl Default for AthenaConfig {
fn default() -> Self {
Self {
output_file: None,
validate_only: false,
verbose: false,
}
}
}
9 changes: 2 additions & 7 deletions src/athena/parser/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,13 @@ pub struct PortMapping {
pub protocol: Protocol,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub enum Protocol {
#[default]
Tcp,
Udp,
}

impl Default for Protocol {
fn default() -> Self {
Protocol::Tcp
}
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum EnvironmentVariable {
Template(String), // {{VAR_NAME}}
Expand Down
4 changes: 1 addition & 3 deletions src/athena/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,4 @@ pub mod ast;
pub mod parser;
pub mod optimized_parser;

pub use ast::*;
pub use parser::{parse_athena_file, AthenaParser};
pub use optimized_parser::OptimizedParser;
pub use parser::parse_athena_file;
13 changes: 13 additions & 0 deletions src/athena/parser/optimized_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ use crate::athena::error::{AthenaError, AthenaResult};
use super::ast::*;

/// Optimized parser with performance improvements and better error handling
#[allow(dead_code)]
pub struct OptimizedParser;

impl OptimizedParser {
/// Parse Athena file with optimized performance and enhanced error reporting
#[allow(dead_code)]
#[allow(dead_code)]
pub fn parse_with_performance_optimizations(input: &str) -> AthenaResult<AthenaFile> {
// Pre-validate input for common issues
Self::pre_validate_input(input)?;
Expand All @@ -19,6 +22,7 @@ impl OptimizedParser {
}

/// Pre-validation for common syntax issues to fail fast
#[allow(dead_code)]
fn pre_validate_input(input: &str) -> AthenaResult<()> {
let trimmed = input.trim();

Expand Down Expand Up @@ -60,6 +64,7 @@ impl OptimizedParser {
}

/// Optimize the AST after parsing for better runtime performance
#[allow(dead_code)]
fn optimize_ast(mut athena_file: AthenaFile) -> AthenaResult<AthenaFile> {
// Sort services by dependency order for faster dependency resolution
athena_file.services.services = Self::topological_sort_services(athena_file.services.services)?;
Expand All @@ -76,6 +81,7 @@ impl OptimizedParser {
}

/// Topological sort services by dependencies for optimal processing order
#[allow(dead_code)]
fn topological_sort_services(services: Vec<Service>) -> AthenaResult<Vec<Service>> {
use std::collections::{HashMap, VecDeque};

Expand Down Expand Up @@ -140,6 +146,7 @@ impl OptimizedParser {
}

/// Optimize individual service configuration
#[allow(dead_code)]
fn optimize_service(service: &mut Service) {
// Remove duplicate environment variables
service.environment.dedup();
Expand All @@ -160,6 +167,7 @@ impl OptimizedParser {
}

/// Apply intelligent defaults based on service patterns
#[allow(dead_code)]
fn apply_intelligent_defaults(athena_file: &mut AthenaFile) {
// Set default deployment if missing
if athena_file.deployment.is_none() {
Expand Down Expand Up @@ -196,6 +204,7 @@ impl OptimizedParser {
}

/// Parse with caching for repeated parsing operations
#[allow(dead_code)]
pub fn parse_with_cache(
input: &str,
cache: &mut HashMap<u64, AthenaFile>
Expand All @@ -221,6 +230,7 @@ impl OptimizedParser {
}

/// Validate syntax without full parsing for quick feedback
#[allow(dead_code)]
pub fn quick_syntax_check(input: &str) -> AthenaResult<()> {
Self::pre_validate_input(input)?;

Expand Down Expand Up @@ -264,6 +274,7 @@ mod tests {
use super::*;

#[test]
#[allow(dead_code)]
fn test_pre_validation() {
assert!(OptimizedParser::pre_validate_input("").is_err());
assert!(OptimizedParser::pre_validate_input("DEPLOYMENT-ID test").is_err());
Expand All @@ -278,6 +289,7 @@ mod tests {
}

#[test]
#[allow(dead_code)]
fn test_unbalanced_service_blocks() {
let invalid_input = r#"
SERVICES SECTION
Expand All @@ -291,6 +303,7 @@ mod tests {
}

#[test]
#[allow(dead_code)]
fn test_quick_syntax_check() {
let invalid_port = r#"
SERVICES SECTION
Expand Down
23 changes: 12 additions & 11 deletions src/boilerplate/fastapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ use std::path::Path;

pub struct FastAPIGenerator;

impl Default for FastAPIGenerator {
fn default() -> Self {
Self::new()
}
}

impl FastAPIGenerator {
pub fn new() -> Self {
Self
Expand Down Expand Up @@ -75,11 +81,6 @@ impl FastAPIGenerator {
"MySQL is not supported for FastAPI projects. Use Flask for MySQL support.".to_string()
));
}
DatabaseType::MySQL => {
return Err(crate::athena::AthenaError::ValidationError(
"MySQL is not supported for FastAPI projects. Use Flask for MySQL support.".to_string()
));
}
}
config_content = replace_template_vars_string(&config_content, &vars);
write_file(base_path.join("app/core/config.py"), &config_content)?;
Expand Down Expand Up @@ -284,7 +285,7 @@ async def get_current_user_info(current_user = Depends(get_current_user)):
}

fn generate_database_files(&self, config: &ProjectConfig, base_path: &Path) -> BoilerplateResult<()> {
let vars = self.get_template_vars(config);
let _vars = self.get_template_vars(config);

write_file(base_path.join("app/database/__init__.py"), "")?;

Expand Down Expand Up @@ -324,7 +325,7 @@ def get_database():
"""Get database instance"""
return db.database
"#;
write_file(base_path.join("app/database/connection.py"), &mongodb_connection)?;
write_file(base_path.join("app/database/connection.py"), mongodb_connection)?;
}
DatabaseType::PostgreSQL => {
let postgres_connection = r#"from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
Expand Down Expand Up @@ -396,7 +397,7 @@ def get_engine():
"""Get database engine"""
return engine
"#;
write_file(base_path.join("app/database/connection.py"), &postgres_connection)?;
write_file(base_path.join("app/database/connection.py"), postgres_connection)?;
}
DatabaseType::MySQL => {
return Err(crate::athena::AthenaError::ValidationError(
Expand All @@ -409,7 +410,7 @@ def get_engine():
}

fn generate_models_and_services(&self, config: &ProjectConfig, base_path: &Path) -> BoilerplateResult<()> {
let vars = self.get_template_vars(config);
let _vars = self.get_template_vars(config);

// Models
write_file(base_path.join("app/models/__init__.py"), "")?;
Expand Down Expand Up @@ -799,13 +800,13 @@ def test_invalid_login():
)
assert response.status_code == 401
"#;
write_file(base_path.join("tests/test_auth.py"), &test_auth)?;
write_file(base_path.join("tests/test_auth.py"), test_auth)?;

Ok(())
}

fn generate_documentation(&self, config: &ProjectConfig, base_path: &Path) -> BoilerplateResult<()> {
let vars = self.get_template_vars(config);
let _vars = self.get_template_vars(config);
let names = ProjectNames::new(&config.name);

let readme = format!(r#"# {project_name}
Expand Down
6 changes: 6 additions & 0 deletions src/boilerplate/flask.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ use std::path::Path;

pub struct FlaskGenerator;

impl Default for FlaskGenerator {
fn default() -> Self {
Self::new()
}
}

impl FlaskGenerator {
pub fn new() -> Self {
Self
Expand Down
10 changes: 8 additions & 2 deletions src/boilerplate/go.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ use std::path::Path;

pub struct GoGenerator;

impl Default for GoGenerator {
fn default() -> Self {
Self::new()
}
}

impl GoGenerator {
pub fn new() -> Self {
Self
Expand Down Expand Up @@ -423,7 +429,7 @@ func VerifyToken(tokenString, jwtSecret, expectedType string) (*Claims, error) {
}

fn generate_models_files(&self, config: &ProjectConfig, base_path: &Path) -> BoilerplateResult<()> {
let vars = self.get_template_vars(config);
let _vars = self.get_template_vars(config);

let models_go = match config.database {
DatabaseType::MySQL => {
Expand Down Expand Up @@ -1421,7 +1427,7 @@ func TestHealth(t *testing.T) {
}

fn generate_documentation(&self, config: &ProjectConfig, base_path: &Path) -> BoilerplateResult<()> {
let vars = self.get_template_vars(config);
let _vars = self.get_template_vars(config);
let names = ProjectNames::new(&config.name);

let readme = format!(r#"# {project_name}
Expand Down
1 change: 1 addition & 0 deletions src/boilerplate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub struct ProjectConfig {
pub directory: String,
pub database: DatabaseType,
pub include_docker: bool,
#[allow(dead_code)]
pub framework: Option<GoFramework>,
}

Expand Down
Loading