use crate::{
BadgeParams, BadgeStyle, RenderOptions, default_label_color, default_message_color,
render_badge_svg_with,
};
pub struct BadgeBuilder<'a> {
style: BadgeStyle,
label: Option<&'a str>,
message: Option<&'a str>,
label_color: Option<&'a str>,
message_color: Option<&'a str>,
logo: Option<&'a str>,
logo_color: Option<&'a str>,
link: Option<&'a str>,
extra_link: Option<&'a str>,
id_suffix: Option<&'a str>,
logo_width: Option<u32>,
}
impl<'a> BadgeBuilder<'a> {
fn new(style: BadgeStyle) -> Self {
Self {
style,
label: None,
message: None,
label_color: None,
message_color: None,
logo: None,
logo_color: None,
link: None,
extra_link: None,
id_suffix: None,
logo_width: None,
}
}
pub fn label(&mut self, label: &'a str) -> &mut Self {
self.label = Some(label);
self
}
pub fn message(&mut self, message: &'a str) -> &mut Self {
self.message = Some(message);
self
}
pub fn label_color(&mut self, color: &'a str) -> &mut Self {
self.label_color = Some(color);
self
}
pub fn message_color(&mut self, color: &'a str) -> &mut Self {
self.message_color = Some(color);
self
}
pub fn logo(&mut self, logo: &'a str) -> &mut Self {
self.logo = Some(logo);
self
}
pub fn logo_color(&mut self, color: &'a str) -> &mut Self {
self.logo_color = Some(color);
self
}
pub fn link(&mut self, link: &'a str) -> &mut Self {
self.link = Some(link);
self
}
pub fn extra_link(&mut self, link: &'a str) -> &mut Self {
self.extra_link = Some(link);
self
}
pub fn id_suffix(&mut self, id_suffix: &'a str) -> &mut Self {
self.id_suffix = Some(id_suffix);
self
}
pub fn logo_width(&mut self, logo_width: u32) -> &mut Self {
self.logo_width = Some(logo_width);
self
}
pub fn build(&self) -> String {
let (label_color, message_color) = if self.style == BadgeStyle::Social {
(None, Some(""))
} else {
(
Some(self.label_color.unwrap_or(default_label_color())),
Some(self.message_color.unwrap_or(default_message_color())),
)
};
render_badge_svg_with(
&BadgeParams {
style: self.style,
label: self.label,
message: self.message,
label_color,
message_color,
logo: self.logo,
logo_color: self.logo_color,
link: self.link,
extra_link: self.extra_link,
},
&{
let mut options = RenderOptions::default().id_suffix(self.id_suffix.unwrap_or(""));
if let Some(width) = self.logo_width {
options = options.logo_width(width);
}
options
},
)
}
}
pub struct Badge;
impl Badge {
pub fn style(style: BadgeStyle) -> BadgeBuilder<'static> {
BadgeBuilder::new(style)
}
pub fn flat() -> BadgeBuilder<'static> {
BadgeBuilder::new(BadgeStyle::Flat)
}
pub fn flat_square() -> BadgeBuilder<'static> {
BadgeBuilder::new(BadgeStyle::FlatSquare)
}
pub fn plastic() -> BadgeBuilder<'static> {
BadgeBuilder::new(BadgeStyle::Plastic)
}
pub fn social() -> BadgeBuilder<'static> {
BadgeBuilder::new(BadgeStyle::Social)
}
pub fn for_the_badge() -> BadgeBuilder<'static> {
BadgeBuilder::new(BadgeStyle::ForTheBadge)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_optimized_flat_badge() {
let mut builder = Badge::style(BadgeStyle::Flat);
let badge = builder
.label("test1")
.message("test2")
.label_color("#000000")
.message_color("#ffffff")
.build();
assert!(badge.contains("test1"));
assert!(badge.contains("test2"));
}
#[test]
fn test_optimized_chaining() {
let badge = Badge::style(BadgeStyle::Plastic)
.label("version")
.message("1.0.0")
.logo("github")
.build();
assert!(badge.contains("version"));
assert!(badge.contains("1.0.0"));
}
#[test]
fn test_alternative_chaining() {
let badge = {
let mut b = Badge::style(BadgeStyle::Flat);
b.label("hello").message("world");
b.build()
};
assert!(badge.contains("hello"));
assert!(badge.contains("world"));
}
#[test]
fn test_configuring_step_by_step() {
let mut badge = Badge::style(BadgeStyle::Flat);
badge.label("no chaining");
badge.message("test");
badge.label_color("#000");
badge.message_color("#fff");
let resp = badge.build();
assert!(resp.contains("no chaining"));
assert!(resp.contains("test"));
}
}