hydro_deploy/rust_crate/
mod.rs1use std::path::PathBuf;
2use std::sync::Arc;
3
4use nameof::name_of;
5use tracing_options::TracingOptions;
6
7use super::Host;
8use crate::rust_crate::build::BuildParams;
9use crate::{HostTargetType, ServiceBuilder};
10
11pub mod build;
12pub mod ports;
13
14pub mod service;
15pub use service::*;
16
17#[cfg(feature = "profile-folding")]
18pub(crate) mod flamegraph;
19pub mod tracing_options;
20
21#[derive(PartialEq, Clone)]
22pub enum CrateTarget {
23 Default,
24 Bin(String),
25 Example(String),
26}
27
28#[derive(Clone)]
35pub struct RustCrate {
36 src: PathBuf,
37 target: CrateTarget,
38 profile: Option<String>,
39 rustflags: Option<String>,
40 target_dir: Option<PathBuf>,
41 build_env: Vec<(String, String)>,
42 is_dylib: bool,
43 no_default_features: bool,
44 features: Option<Vec<String>>,
45 config: Vec<String>,
46 tracing: Option<TracingOptions>,
47 args: Vec<String>,
48 display_name: Option<String>,
49}
50
51impl RustCrate {
52 pub fn new(src: impl Into<PathBuf>) -> Self {
56 Self {
57 src: src.into(),
58 target: CrateTarget::Default,
59 profile: None,
60 rustflags: None,
61 target_dir: None,
62 build_env: vec![],
63 is_dylib: false,
64 no_default_features: false,
65 features: None,
66 config: vec![],
67 tracing: None,
68 args: vec![],
69 display_name: None,
70 }
71 }
72
73 pub fn bin(mut self, bin: impl Into<String>) -> Self {
76 if self.target != CrateTarget::Default {
77 panic!("{} already set", name_of!(target in Self));
78 }
79
80 self.target = CrateTarget::Bin(bin.into());
81 self
82 }
83
84 pub fn example(mut self, example: impl Into<String>) -> Self {
87 if self.target != CrateTarget::Default {
88 panic!("{} already set", name_of!(target in Self));
89 }
90
91 self.target = CrateTarget::Example(example.into());
92 self
93 }
94
95 pub fn profile(mut self, profile: impl Into<String>) -> Self {
98 if self.profile.is_some() {
99 panic!("{} already set", name_of!(profile in Self));
100 }
101
102 self.profile = Some(profile.into());
103 self
104 }
105
106 pub fn rustflags(mut self, rustflags: impl Into<String>) -> Self {
107 if self.rustflags.is_some() {
108 panic!("{} already set", name_of!(rustflags in Self));
109 }
110
111 self.rustflags = Some(rustflags.into());
112 self
113 }
114
115 pub fn target_dir(mut self, target_dir: impl Into<PathBuf>) -> Self {
116 if self.target_dir.is_some() {
117 panic!("{} already set", name_of!(target_dir in Self));
118 }
119
120 self.target_dir = Some(target_dir.into());
121 self
122 }
123
124 pub fn build_env(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
125 self.build_env.push((key.into(), value.into()));
126 self
127 }
128
129 pub fn set_is_dylib(mut self, is_dylib: bool) -> Self {
130 self.is_dylib = is_dylib;
131 self
132 }
133
134 pub fn no_default_features(mut self) -> Self {
135 self.no_default_features = true;
136 self
137 }
138
139 pub fn features(mut self, features: impl IntoIterator<Item = impl Into<String>>) -> Self {
140 if self.features.is_none() {
141 self.features = Some(vec![]);
142 }
143
144 self.features
145 .as_mut()
146 .unwrap()
147 .extend(features.into_iter().map(|s| s.into()));
148
149 self
150 }
151
152 pub fn config(mut self, config: impl Into<String>) -> Self {
153 self.config.push(config.into());
154 self
155 }
156
157 pub fn tracing(mut self, perf: impl Into<TracingOptions>) -> Self {
158 if self.tracing.is_some() {
159 panic!("{} already set", name_of!(tracing in Self));
160 }
161
162 self.tracing = Some(perf.into());
163 self
164 }
165
166 pub fn args(mut self, args: impl IntoIterator<Item = impl Into<String>>) -> Self {
168 self.args.extend(args.into_iter().map(|s| s.into()));
169 self
170 }
171
172 pub fn display_name(mut self, display_name: impl Into<String>) -> Self {
174 if self.display_name.is_some() {
175 panic!("{} already set", name_of!(display_name in Self));
176 }
177
178 self.display_name = Some(display_name.into());
179 self
180 }
181
182 pub fn get_build_params(&self, target: HostTargetType) -> BuildParams {
183 let (bin, example) = match &self.target {
184 CrateTarget::Default => (None, None),
185 CrateTarget::Bin(bin) => (Some(bin.clone()), None),
186 CrateTarget::Example(example) => (None, Some(example.clone())),
187 };
188
189 BuildParams::new(
190 self.src.clone(),
191 bin,
192 example,
193 self.profile.clone(),
194 self.rustflags.clone(),
195 self.target_dir.clone(),
196 self.build_env.clone(),
197 self.no_default_features,
198 target,
199 self.is_dylib,
200 self.features.clone(),
201 self.config.clone(),
202 )
203 }
204}
205
206impl ServiceBuilder for RustCrate {
207 type Service = RustCrateService;
208 fn build(self, id: usize, on: Arc<dyn Host>) -> Self::Service {
209 let build_params = self.get_build_params(on.target_type());
210
211 RustCrateService::new(
212 id,
213 on,
214 build_params,
215 self.tracing,
216 Some(self.args),
217 self.display_name,
218 vec![],
219 )
220 }
221}