improve badge generation performance

This commit is contained in:
Sam Rijs 2018-03-07 18:53:29 +11:00
parent 8ec8952304
commit 5885ec3f8c
4 changed files with 27 additions and 25 deletions

1
Cargo.lock generated
View file

@ -32,6 +32,7 @@ name = "badge"
version = "0.2.0" version = "0.2.0"
dependencies = [ dependencies = [
"base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rusttype 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "rusttype 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]

View file

@ -12,4 +12,5 @@ path = "badge.rs"
[dependencies] [dependencies]
base64 = "0.9.0" base64 = "0.9.0"
lazy_static = "1.0.0"
rusttype = "0.4.0" rusttype = "0.4.0"

View file

@ -1,6 +1,7 @@
//! Simple badge generator //! Simple badge generator
extern crate base64; extern crate base64;
#[macro_use] extern crate lazy_static;
extern crate rusttype; extern crate rusttype;
@ -34,31 +35,37 @@ impl Default for BadgeOptions {
} }
pub struct Badge { struct BadgeStaticData {
options: BadgeOptions,
font: Font<'static>, font: Font<'static>,
scale: Scale, scale: Scale,
offset: Point<f32>, offset: Point<f32>
} }
impl Badge { lazy_static! {
pub fn new(options: BadgeOptions) -> Result<Badge, String> { static ref DATA: BadgeStaticData = {
let collection = FontCollection::from_bytes(FONT_DATA); let collection = FontCollection::from_bytes(FONT_DATA);
// this should never fail in practice let font = collection.into_font().expect("Failed to load font data");
let font = try!(collection.into_font().ok_or("Failed to load font data".to_owned()));
let scale = Scale { let scale = Scale {
x: FONT_SIZE, x: FONT_SIZE,
y: FONT_SIZE, y: FONT_SIZE,
}; };
let v_metrics = font.v_metrics(scale); let v_metrics = font.v_metrics(scale);
let offset = point(0.0, v_metrics.ascent); let offset = point(0.0, v_metrics.ascent);
Ok(Badge {
options: options, BadgeStaticData { font, scale, offset }
font: font, };
scale: scale, }
offset: offset,
})
pub struct Badge {
options: BadgeOptions
}
impl Badge {
pub fn new(options: BadgeOptions) -> Badge {
Badge { options }
} }
@ -117,7 +124,7 @@ impl Badge {
fn calculate_width(&self, text: &str) -> u32 { fn calculate_width(&self, text: &str) -> u32 {
let glyphs: Vec<PositionedGlyph> = let glyphs: Vec<PositionedGlyph> =
self.font.layout(text, self.scale, self.offset).collect(); DATA.font.layout(text, DATA.scale, DATA.offset).collect();
let width = glyphs.iter() let width = glyphs.iter()
.rev() .rev()
.filter_map(|g| { .filter_map(|g| {
@ -140,17 +147,11 @@ mod tests {
BadgeOptions::default() BadgeOptions::default()
} }
#[test]
fn test_new() {
assert!(Badge::new(options()).is_ok());
}
#[test] #[test]
fn test_calculate_width() { fn test_calculate_width() {
let badge = Badge::new(options()).unwrap(); let badge = Badge::new(options());
assert_eq!(badge.calculate_width("build"), 31); assert_eq!(badge.calculate_width("build"), 29);
assert_eq!(badge.calculate_width("passing"), 48); assert_eq!(badge.calculate_width("passing"), 44);
} }
#[test] #[test]
@ -164,7 +165,7 @@ mod tests {
status: "passing".to_owned(), status: "passing".to_owned(),
..BadgeOptions::default() ..BadgeOptions::default()
}; };
let badge = Badge::new(options).unwrap(); let badge = Badge::new(options);
file.write_all(badge.to_svg().as_bytes()).unwrap(); file.write_all(badge.to_svg().as_bytes()).unwrap();
} }
} }

View file

@ -39,7 +39,6 @@ pub fn badge(analysis_outcome: Option<&AnalyzeDependenciesOutcome>) -> Badge {
}; };
Badge::new(opts) Badge::new(opts)
.expect("failed to create badge")
} }
pub fn response(analysis_outcome: Option<&AnalyzeDependenciesOutcome>) -> Response { pub fn response(analysis_outcome: Option<&AnalyzeDependenciesOutcome>) -> Response {