-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: move to a pipeline-based code processing system
- Loading branch information
1 parent
9885cb6
commit 02bef08
Showing
6 changed files
with
183 additions
and
121 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
use std::fmt::{self, Write}; | ||
|
||
use chrono::{DateTime, Local}; | ||
use const_format::formatcp; | ||
|
||
use crate::consts::{CRATE_NAME, CRATE_REPOSITORY, SHORT_VERSION}; | ||
use crate::display::format_date; | ||
use crate::pipeline::Stage; | ||
use crate::quotes::Quotes; | ||
|
||
#[derive(Debug, Clone)] | ||
pub struct Banner { | ||
pub quotes: Quotes, | ||
pub deterministic: bool, | ||
} | ||
|
||
impl Banner { | ||
fn write_banner<W: Write + ?Sized>(&self, out: &mut W) -> fmt::Result { | ||
const MIN_WIDTH: usize = 56; | ||
const PADDING: usize = 4; | ||
|
||
const ART: &[&str] = &[ | ||
r#" ) ( ("#, | ||
r#" ( /( ( )\ ) )\"#, | ||
r#" ( )\()) ))\ ( (()/(((_)"#, | ||
r#" )\ ((_)\ /((_) )\ ) ((_))_"#, | ||
r#" ((_)| |(_)(_))( _(_/( _| || |"#, | ||
r#"/ _| | '_ \| || || ' \))/ _` || |"#, | ||
r#"\__| |_.__/ \_,_||_||_| \__,_||_|"#, | ||
]; | ||
|
||
let generated_at = if self.deterministic { | ||
format_date(DateTime::UNIX_EPOCH) | ||
} else { | ||
format_date(Local::now()) | ||
}; | ||
|
||
let quote = if self.deterministic { | ||
self.quotes.get(0).expect("we dont have a single quote :'(") | ||
} else { | ||
self.quotes.random() | ||
}; | ||
|
||
let line1 = formatcp!("{CRATE_NAME} {SHORT_VERSION}"); | ||
let line2 = formatcp!("{CRATE_REPOSITORY}"); | ||
let line3 = format!("Generated at: {}", generated_at); | ||
|
||
let art_width = ART.iter().map(|x| x.len()).max().unwrap(); | ||
let banner_width = MIN_WIDTH.max(art_width).max(line1.len()).max(line2.len()) + PADDING; | ||
|
||
writeln!(out, "/**")?; | ||
writeln!(out, " *")?; | ||
for line in ART { | ||
writeln!(out, " * {:^1$}", line, banner_width)?; | ||
} | ||
writeln!(out, " * ")?; | ||
|
||
writeln!(out, " * {:^1$}", line1, banner_width)?; | ||
writeln!(out, " * {:^1$}", line2, banner_width)?; | ||
writeln!(out, " *")?; | ||
writeln!(out, " * {:^1$}", line3, banner_width)?; | ||
writeln!(out, " *")?; | ||
writeln!(out, " *")?; | ||
quote.lines().try_for_each(|x| writeln!(out, " * {x}"))?; | ||
writeln!(out, " * - {}", quote.author())?; | ||
writeln!(out, " *")?; | ||
writeln!(out, " */")?; | ||
writeln!(out)?; | ||
|
||
Ok(()) | ||
} | ||
} | ||
|
||
impl Stage for Banner { | ||
fn name() -> &'static str { | ||
"banner" | ||
} | ||
|
||
fn process(&mut self, code: String) -> eyre::Result<String> { | ||
const ESTIMATED_BANNER_SIZE: usize = 1024; | ||
|
||
let mut out = String::with_capacity(ESTIMATED_BANNER_SIZE + code.len()); | ||
|
||
self.write_banner(&mut out) | ||
.expect("writing to String should never fail"); | ||
|
||
out.push_str(&code); | ||
Ok(out) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
use eyre::{Context, Result}; | ||
|
||
use crate::banner::Banner; | ||
use crate::bundler::Bundler; | ||
use crate::formatter::Formatter; | ||
use crate::source::Sources; | ||
|
||
pub trait Stage: Sized { | ||
fn name() -> &'static str; | ||
fn process(&mut self, code: String) -> Result<String>; | ||
} | ||
|
||
impl<S: Stage> Stage for Option<S> { | ||
fn name() -> &'static str { | ||
S::name() | ||
} | ||
|
||
fn process(&mut self, code: String) -> Result<String> { | ||
match self.as_mut() { | ||
None => Ok(code), | ||
Some(stage) => stage.process(code), | ||
} | ||
} | ||
} | ||
|
||
#[derive(Debug, Clone)] | ||
pub struct Pipeline { | ||
pub bundler: Bundler, | ||
pub banner: Banner, | ||
pub formatter: Option<Formatter>, | ||
} | ||
|
||
impl Pipeline { | ||
pub fn process(&mut self, sources: &Sources) -> Result<String> { | ||
let mut out = self.bundler.bundle(sources)?; | ||
|
||
out = run_stage(&mut self.banner, out)?; | ||
out = run_stage(&mut self.formatter, out)?; | ||
|
||
Ok(out) | ||
} | ||
} | ||
|
||
fn run_stage<S: Stage>(stage: &mut S, code: String) -> Result<String> { | ||
stage | ||
.process(code) | ||
.with_context(|| format!("stage '{}' failed", S::name())) | ||
} |