use std::path::PathBuf;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AnnotationProcessor {
pub name: String,
pub supported_annotations: Vec<String>,
pub supported_options: Vec<String>,
pub class_path: Vec<PathBuf>,
}
impl AnnotationProcessor {
pub fn new(name: impl Into<String>) -> Self {
Self {
name: name.into(),
supported_annotations: Vec::new(),
supported_options: Vec::new(),
class_path: Vec::new(),
}
}
pub fn with_annotations(mut self, annotations: Vec<String>) -> Self {
self.supported_annotations = annotations;
self
}
pub fn with_options(mut self, options: Vec<String>) -> Self {
self.supported_options = options;
self
}
pub fn with_class_path(mut self, class_path: Vec<PathBuf>) -> Self {
self.class_path = class_path;
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AnnotationProcessorConfig {
pub processors: Vec<AnnotationProcessor>,
pub options: Vec<(String, String)>,
pub generated_sources_directory: PathBuf,
pub generated_classes_directory: PathBuf,
}
impl Default for AnnotationProcessorConfig {
fn default() -> Self {
Self {
processors: Vec::new(),
options: Vec::new(),
generated_sources_directory: PathBuf::from("target/generated-sources/annotations"),
generated_classes_directory: PathBuf::from("target/generated-sources/annotations"),
}
}
}
impl AnnotationProcessorConfig {
pub fn new() -> Self {
Self::default()
}
pub fn add_processor(&mut self, processor: AnnotationProcessor) {
self.processors.push(processor);
}
pub fn add_option(&mut self, key: String, value: String) {
self.options.push((key, value));
}
pub fn get_processor_class_paths(&self) -> Vec<PathBuf> {
let mut paths = Vec::new();
for processor in &self.processors {
paths.extend(processor.class_path.clone());
}
paths.sort();
paths.dedup();
paths
}
}
pub mod common {
use super::*;
pub fn mapstruct_processor() -> AnnotationProcessor {
AnnotationProcessor::new("org.mapstruct.ap.MappingProcessor")
.with_annotations(vec![
"org.mapstruct.Mapping".to_string(),
"org.mapstruct.Mappings".to_string(),
"org.mapstruct.Mapper".to_string(),
])
}
pub fn autovalue_processor() -> AnnotationProcessor {
AnnotationProcessor::new("com.google.auto.value.processor.AutoValueProcessor")
.with_annotations(vec![
"com.google.auto.value.AutoValue".to_string(),
"com.google.auto.value.AutoValue.Builder".to_string(),
])
}
pub fn lombok_processor() -> AnnotationProcessor {
AnnotationProcessor::new("lombok.launch.AnnotationProcessorHider$AnnotationProcessor")
.with_annotations(vec![
"lombok.Data".to_string(),
"lombok.Value".to_string(),
"lombok.Builder".to_string(),
"lombok.AllArgsConstructor".to_string(),
"lombok.NoArgsConstructor".to_string(),
])
}
pub fn dagger_processor() -> AnnotationProcessor {
AnnotationProcessor::new("dagger.internal.codegen.ComponentProcessor")
.with_annotations(vec![
"dagger.Component".to_string(),
"dagger.Module".to_string(),
"dagger.Provides".to_string(),
"dagger.Binds".to_string(),
])
}
pub fn common_processors() -> Vec<AnnotationProcessor> {
vec![
mapstruct_processor(),
autovalue_processor(),
lombok_processor(),
dagger_processor(),
]
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_annotation_processor_creation() {
let processor = AnnotationProcessor::new("test.Processor")
.with_annotations(vec!["com.example.Test".to_string()]);
assert_eq!(processor.name, "test.Processor");
assert_eq!(processor.supported_annotations.len(), 1);
}
#[test]
fn test_common_processors() {
let processors = common::common_processors();
assert!(!processors.is_empty());
}
}