use syn::{Block, Generics, Ident, Type, Visibility};
#[derive(Debug, Clone, PartialEq)]
pub enum ComponentType {
PropsBased {
props_type: Box<Type>,
props_param_name: Ident,
},
DirectParams { parameters: Vec<ComponentParameter> },
NoParams,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ComponentParameter {
pub name: Ident,
pub param_type: Type,
}
#[derive(Debug, Clone)]
pub struct ComponentInfo {
pub component_type: ComponentType,
pub name: Ident,
pub visibility: Visibility,
pub block: Block,
pub generics: Generics,
pub return_type: Type,
}
impl ComponentInfo {
pub fn new(
component_type: ComponentType,
name: Ident,
visibility: Visibility,
block: Block,
generics: Generics,
return_type: Type,
) -> Self {
Self {
component_type,
name,
visibility,
block,
generics,
return_type,
}
}
pub fn props_struct_name(&self) -> Ident {
Ident::new(&format!("{}Props", self.name), self.name.span())
}
pub fn component_struct_name(&self) -> Ident {
Ident::new(&format!("{}Component", self.name), self.name.span())
}
pub fn original_function_name(&self) -> Ident {
Ident::new(&format!("__original_{}", self.name), self.name.span())
}
pub fn has_parameters(&self) -> bool {
match &self.component_type {
ComponentType::PropsBased { .. } => true,
ComponentType::DirectParams { parameters } => !parameters.is_empty(),
ComponentType::NoParams => false,
}
}
pub fn has_generics(&self) -> bool {
!self.generics.params.is_empty()
}
pub fn direct_parameters(&self) -> Option<&Vec<ComponentParameter>> {
match &self.component_type {
ComponentType::DirectParams { parameters } => Some(parameters),
_ => None,
}
}
pub fn props_info(&self) -> Option<(&Type, &Ident)> {
match &self.component_type {
ComponentType::PropsBased {
props_type,
props_param_name,
} => Some((props_type, props_param_name)),
_ => None,
}
}
}
impl ComponentParameter {
pub fn new(name: Ident, param_type: Type) -> Self {
Self { name, param_type }
}
}
#[derive(Debug, Clone)]
pub struct CodeGenConfig {
pub debug_info: bool,
pub generate_docs: bool,
pub children_support: bool,
pub custom_derives: Vec<String>,
}
impl Default for CodeGenConfig {
fn default() -> Self {
Self {
debug_info: false,
generate_docs: true,
children_support: true,
custom_derives: vec!["Clone".to_string()],
}
}
}
#[derive(Debug, Clone)]
pub struct ValidationConfig {
pub allow_async: bool,
pub allow_unsafe: bool,
pub max_direct_params: usize,
pub require_explicit_return: bool,
}
impl Default for ValidationConfig {
fn default() -> Self {
Self {
allow_async: false,
allow_unsafe: false,
max_direct_params: 15,
require_explicit_return: true,
}
}
}
#[derive(Debug, Clone)]
pub struct GeneratedComponentMetadata {
pub function_name: Ident,
pub props_struct_name: Option<Ident>,
pub component_struct_name: Ident,
pub supports_children: bool,
pub generated_methods: Vec<String>,
}
impl GeneratedComponentMetadata {
pub fn props_based(
function_name: Ident,
props_struct_name: Ident,
component_struct_name: Ident,
) -> Self {
Self {
function_name,
props_struct_name: Some(props_struct_name),
component_struct_name,
supports_children: true,
generated_methods: vec![
"new".to_string(),
"with_children".to_string(),
"render".to_string(),
],
}
}
pub fn direct_params(
function_name: Ident,
props_struct_name: Ident,
component_struct_name: Ident,
parameter_names: Vec<String>,
) -> Self {
let mut methods = vec![
"new".to_string(),
"with_children".to_string(),
"render".to_string(),
];
methods.extend(parameter_names);
Self {
function_name,
props_struct_name: Some(props_struct_name),
component_struct_name,
supports_children: true,
generated_methods: methods,
}
}
pub fn no_params(
function_name: Ident,
props_struct_name: Ident,
component_struct_name: Ident,
) -> Self {
Self {
function_name,
props_struct_name: Some(props_struct_name),
component_struct_name,
supports_children: true,
generated_methods: vec![
"new".to_string(),
"with_children".to_string(),
"render".to_string(),
],
}
}
}