pop_common/
build.rs

1// SPDX-License-Identifier: GPL-3.0
2
3use std::{
4	fmt,
5	path::{Path, PathBuf},
6};
7use strum::{EnumMessage as _, VariantArray as _};
8use strum_macros::{AsRefStr, EnumMessage, EnumString, VariantArray};
9
10/// Enum representing a build profile.
11#[derive(AsRefStr, Clone, Default, Debug, EnumString, EnumMessage, VariantArray, Eq, PartialEq)]
12pub enum Profile {
13	/// Debug profile, optimized for debugging.
14	#[strum(serialize = "debug", message = "Debug", detailed_message = "Optimized for debugging.")]
15	Debug,
16	/// Release profile, optimized without any debugging functionality.
17	#[default]
18	#[strum(
19		serialize = "release",
20		message = "Release",
21		detailed_message = "Optimized without any debugging functionality."
22	)]
23	Release,
24	/// Production profile, optimized for ultimate performance.
25	#[strum(
26		serialize = "production",
27		message = "Production",
28		detailed_message = "Optimized for ultimate performance."
29	)]
30	Production,
31}
32
33impl Profile {
34	/// Returns the corresponding path to the target directory.
35	pub fn target_directory(&self, path: &Path) -> PathBuf {
36		match self {
37			Profile::Release => path.join("target/release"),
38			Profile::Debug => path.join("target/debug"),
39			Profile::Production => path.join("target/production"),
40		}
41	}
42
43	/// Returns the variants of the enum.
44	pub fn get_variants() -> Vec<(String, String)> {
45		Profile::VARIANTS
46			.iter()
47			.map(|profile| {
48				(
49					profile.get_message().unwrap_or(profile.as_ref()).to_string(),
50					profile.get_detailed_message().unwrap_or_default().to_string(),
51				)
52			})
53			.collect()
54	}
55}
56
57impl From<Profile> for bool {
58	fn from(value: Profile) -> Self {
59		value != Profile::Debug
60	}
61}
62
63impl From<bool> for Profile {
64	fn from(value: bool) -> Self {
65		if value { Profile::Release } else { Profile::Debug }
66	}
67}
68
69impl fmt::Display for Profile {
70	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71		match self {
72			Self::Debug => write!(f, "debug"),
73			Self::Release => write!(f, "release"),
74			Self::Production => write!(f, "production"),
75		}
76	}
77}
78
79#[cfg(test)]
80mod tests {
81	use super::*;
82	use std::path::Path;
83	use strum::EnumMessage;
84
85	#[test]
86	fn profile_from_string() {
87		assert_eq!("debug".parse::<Profile>().unwrap(), Profile::Debug);
88		assert_eq!("release".parse::<Profile>().unwrap(), Profile::Release);
89		assert_eq!("production".parse::<Profile>().unwrap(), Profile::Production);
90	}
91
92	#[test]
93	fn profile_detailed_message() {
94		assert_eq!(Profile::Debug.get_detailed_message(), Some("Optimized for debugging."));
95		assert_eq!(
96			Profile::Release.get_detailed_message(),
97			Some("Optimized without any debugging functionality.")
98		);
99		assert_eq!(
100			Profile::Production.get_detailed_message(),
101			Some("Optimized for ultimate performance.")
102		);
103	}
104
105	#[test]
106	fn profile_target_directory() {
107		let base_path = Path::new("/example/path");
108
109		assert_eq!(
110			Profile::Debug.target_directory(base_path),
111			Path::new("/example/path/target/debug")
112		);
113		assert_eq!(
114			Profile::Release.target_directory(base_path),
115			Path::new("/example/path/target/release")
116		);
117		assert_eq!(
118			Profile::Production.target_directory(base_path),
119			Path::new("/example/path/target/production")
120		);
121	}
122
123	#[test]
124	fn profile_default() {
125		let default_profile = Profile::default();
126		assert_eq!(default_profile, Profile::Release);
127	}
128
129	#[test]
130	fn profile_from_bool() {
131		assert_eq!(Profile::from(true), Profile::Release);
132		assert_eq!(Profile::from(false), Profile::Debug);
133	}
134
135	#[test]
136	fn profile_into_bool() {
137		assert!(!bool::from(Profile::Debug));
138		assert!(bool::from(Profile::Release));
139		assert!(bool::from(Profile::Production));
140	}
141}