use crate::icon::Icon;
#[derive(Debug, Clone, Default)]
pub struct AboutMetadata {
pub name: Option<String>,
pub version: Option<String>,
pub short_version: Option<String>,
pub authors: Option<Vec<String>>,
pub comments: Option<String>,
pub copyright: Option<String>,
pub license: Option<String>,
pub website: Option<String>,
pub website_label: Option<String>,
pub credits: Option<String>,
pub icon: Option<Icon>,
}
impl AboutMetadata {
#[allow(unused)]
pub(crate) fn full_version(&self) -> Option<String> {
Some(format!(
"{}{}",
(self.version.as_ref())?,
(self.short_version.as_ref())
.map(|v| format!(" ({v})"))
.unwrap_or_default()
))
}
}
#[macro_export]
#[doc(hidden)]
macro_rules! from_cargo_metadata {
() => {{
#[allow(unused_mut)]
let mut m = $crate::about_metadata::AboutMetadata {
name: Some(::std::env!("CARGO_PKG_NAME").into()),
version: Some(::std::env!("CARGO_PKG_VERSION").into()),
short_version: Some(::std::format!(
"{}.{}",
env!("CARGO_PKG_VERSION_MAJOR"),
env!("CARGO_PKG_VERSION_MINOR"),
)),
..::std::default::Default::default()
};
#[cfg(not(target_os = "macos"))]
{
let authors = env!("CARGO_PKG_AUTHORS")
.split(':')
.map(|a| a.trim().to_string())
.collect::<::std::vec::Vec<_>>();
m.authors = if !authors.is_empty() {
Some(authors)
} else {
None
};
#[inline]
fn non_empty(s: &str) -> Option<String> {
if !s.is_empty() {
Some(s.to_string())
} else {
None
}
}
m.comments = non_empty(::std::env!("CARGO_PKG_DESCRIPTION"));
m.license = non_empty(::std::env!("CARGO_PKG_LICENSE"));
m.website = non_empty(::std::env!("CARGO_PKG_HOMEPAGE"));
}
m
}};
}
pub use from_cargo_metadata;
#[derive(Clone, Debug, Default)]
pub struct AboutMetadataBuilder(AboutMetadata);
impl AboutMetadataBuilder {
pub fn new() -> Self {
Default::default()
}
pub fn name<S: Into<String>>(mut self, name: Option<S>) -> Self {
self.0.name = name.map(|s| s.into());
self
}
pub fn version<S: Into<String>>(mut self, version: Option<S>) -> Self {
self.0.version = version.map(|s| s.into());
self
}
pub fn short_version<S: Into<String>>(mut self, short_version: Option<S>) -> Self {
self.0.short_version = short_version.map(|s| s.into());
self
}
pub fn authors(mut self, authors: Option<Vec<String>>) -> Self {
self.0.authors = authors;
self
}
pub fn comments<S: Into<String>>(mut self, comments: Option<S>) -> Self {
self.0.comments = comments.map(|s| s.into());
self
}
pub fn copyright<S: Into<String>>(mut self, copyright: Option<S>) -> Self {
self.0.copyright = copyright.map(|s| s.into());
self
}
pub fn license<S: Into<String>>(mut self, license: Option<S>) -> Self {
self.0.license = license.map(|s| s.into());
self
}
pub fn website<S: Into<String>>(mut self, website: Option<S>) -> Self {
self.0.website = website.map(|s| s.into());
self
}
pub fn website_label<S: Into<String>>(mut self, website_label: Option<S>) -> Self {
self.0.website_label = website_label.map(|s| s.into());
self
}
pub fn credits<S: Into<String>>(mut self, credits: Option<S>) -> Self {
self.0.credits = credits.map(|s| s.into());
self
}
pub fn icon(mut self, icon: Option<Icon>) -> Self {
self.0.icon = icon;
self
}
pub fn build(self) -> AboutMetadata {
self.0
}
}
#[cfg(test)]
mod tests {
#[test]
fn test_build_from_metadata() {
let m = from_cargo_metadata!();
assert_eq!(m.name, Some("muda".to_string()));
assert!(m.version.is_some());
assert!(m.short_version.is_some());
#[cfg(not(target_os = "macos"))]
{
assert!(matches!(m.authors, Some(a) if !a.is_empty()));
assert!(m.comments.is_some());
assert!(m.license.is_some());
}
}
}