actr_cli/commands/codegen/
scaffold.rs1use 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) {}