Skip to main content

actr_cli/commands/codegen/
scaffold.rs

1use crate::commands::SupportedLanguage;
2use crate::commands::codegen::metadata::{ActrGenMetadata, load_metadata};
3use crate::commands::codegen::proto_model::ProtoModel;
4use crate::commands::codegen::traits::GenContext;
5use crate::error::Result;
6use std::path::PathBuf;
7
8#[derive(Debug, Clone)]
9pub struct ScaffoldCatalog {
10    pub local_services: Vec<ScaffoldService>,
11    pub remote_services: Vec<ScaffoldService>,
12}
13
14#[derive(Debug, Clone)]
15pub struct ScaffoldService {
16    pub name: String,
17    pub package: String,
18    pub proto_file: PathBuf,
19    pub handler_interface: Option<String>,
20    pub workload_type: Option<String>,
21    pub dispatcher_type: Option<String>,
22    pub client_type: Option<String>,
23    pub actr_type: Option<String>,
24    pub methods: Vec<ScaffoldMethod>,
25}
26
27#[derive(Debug, Clone)]
28pub struct ScaffoldMethod {
29    pub name: String,
30    pub snake_name: String,
31    pub input_type: String,
32    pub output_type: String,
33    pub route_key: String,
34}
35
36impl ScaffoldCatalog {
37    pub fn load(context: &GenContext, language: SupportedLanguage) -> Result<Self> {
38        let expected_language = language_key(language);
39        let metadata = load_metadata(&context.output)?
40            .filter(|metadata| metadata.language == expected_language)
41            .unwrap_or_else(|| ActrGenMetadata::from_proto_model(language, &context.proto_model));
42        Ok(Self::from_metadata(&metadata))
43    }
44
45    fn from_metadata(metadata: &ActrGenMetadata) -> Self {
46        Self {
47            local_services: metadata
48                .local_services
49                .iter()
50                .map(|service| ScaffoldService {
51                    name: service.name.clone(),
52                    package: service.package.clone(),
53                    proto_file: PathBuf::from(&service.proto_file),
54                    handler_interface: Some(service.handler_interface.clone()),
55                    workload_type: Some(service.workload_type.clone()),
56                    dispatcher_type: Some(service.dispatcher_type.clone()),
57                    client_type: None,
58                    actr_type: None,
59                    methods: service
60                        .methods
61                        .iter()
62                        .map(|method| ScaffoldMethod {
63                            name: method.name.clone(),
64                            snake_name: method.snake_name.clone(),
65                            input_type: method.input_type.clone(),
66                            output_type: method.output_type.clone(),
67                            route_key: method.route_key.clone(),
68                        })
69                        .collect(),
70                })
71                .collect(),
72            remote_services: metadata
73                .remote_services
74                .iter()
75                .map(|service| ScaffoldService {
76                    name: service.name.clone(),
77                    package: service.package.clone(),
78                    proto_file: PathBuf::from(&service.proto_file),
79                    handler_interface: None,
80                    workload_type: None,
81                    dispatcher_type: None,
82                    client_type: Some(service.client_type.clone()),
83                    actr_type: Some(service.actr_type.clone()),
84                    methods: service
85                        .methods
86                        .iter()
87                        .map(|method| ScaffoldMethod {
88                            name: method.name.clone(),
89                            snake_name: method.snake_name.clone(),
90                            input_type: method.input_type.clone(),
91                            output_type: method.output_type.clone(),
92                            route_key: method.route_key.clone(),
93                        })
94                        .collect(),
95                })
96                .collect(),
97        }
98    }
99
100    pub fn has_any_methods(&self) -> bool {
101        self.local_services
102            .iter()
103            .any(|service| !service.methods.is_empty())
104            || self
105                .remote_services
106                .iter()
107                .any(|service| !service.methods.is_empty())
108    }
109}
110
111fn language_key(language: SupportedLanguage) -> &'static str {
112    match language {
113        SupportedLanguage::Rust => "rust",
114        SupportedLanguage::Python => "python",
115        SupportedLanguage::Swift => "swift",
116        SupportedLanguage::Kotlin => "kotlin",
117        SupportedLanguage::TypeScript => "typescript",
118    }
119}
120
121#[allow(dead_code)]
122fn _proto_model_is_retained_for_generation_ordering(_proto_model: &ProtoModel) {}