use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
use std::collections::HashMap;
use crate::generation::{Language, ProtocolContext};
use crate::protocols::{Protocol, Role};
#[derive(Debug, Clone)]
pub struct GenerationContext {
pub protocol: Protocol,
pub role: Role,
pub language: Language,
pub variables: HashMap<String, JsonValue>,
pub metadata: GenerationMetadata,
pub protocol_context: Option<ProtocolContext>,
pub output_dir: Option<std::path::PathBuf>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GenerationMetadata {
pub project_name: String,
pub version: String,
pub description: Option<String>,
pub author: Option<String>,
pub license: Option<String>,
pub repository: Option<String>,
}
impl GenerationContext {
pub fn new(protocol: Protocol, role: Role, language: Language) -> Self {
Self {
protocol,
role,
language,
variables: HashMap::new(),
metadata: GenerationMetadata::default(),
protocol_context: None,
output_dir: None,
}
}
pub fn add_variable(&mut self, key: String, value: JsonValue) {
self.variables.insert(key, value);
}
pub fn validate(&self) -> Result<(), crate::generation::GenerationError> {
if self.metadata.project_name.is_empty() {
return Err(crate::generation::GenerationError::ValidationError(
"Project name is required".to_string(),
));
}
self.protocol.validate_role(&self.role).map_err(|e| {
crate::generation::GenerationError::ValidationError(format!(
"Invalid role for protocol: {e}"
))
})?;
Ok(())
}
}
impl Default for GenerationMetadata {
fn default() -> Self {
Self {
project_name: String::new(),
version: "0.1.0".to_string(),
description: None,
author: None,
license: None,
repository: None,
}
}
}
#[derive(Debug, Clone)]
pub struct RenderContext {
pub data: JsonValue,
pub variables: HashMap<String, JsonValue>,
}
impl RenderContext {
pub fn new() -> Self {
Self {
data: JsonValue::Object(serde_json::Map::new()),
variables: HashMap::new(),
}
}
pub fn add_variable(&mut self, key: &str, value: JsonValue) {
self.variables.insert(key.to_string(), value.clone());
if let Some(obj) = self.data.as_object_mut() {
obj.insert(key.to_string(), value);
}
}
pub fn has_variable(&self, key: &str) -> bool {
self.variables.contains_key(key)
}
}
impl Default for RenderContext {
fn default() -> Self {
Self::new()
}
}