feat: builder pattern
This commit is contained in:
parent
0974abc81d
commit
142ea69ff7
61
src/main.rs
61
src/main.rs
|
@ -5,10 +5,12 @@ mod text;
|
||||||
mod ts;
|
mod ts;
|
||||||
mod utils;
|
mod utils;
|
||||||
mod watch;
|
mod watch;
|
||||||
|
mod website;
|
||||||
|
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use build::Hashed;
|
use build::Hashed;
|
||||||
use camino::{Utf8Path, Utf8PathBuf};
|
use camino::{Utf8Path, Utf8PathBuf};
|
||||||
|
@ -19,6 +21,7 @@ use gray_matter::Matter;
|
||||||
use hypertext::{Raw, Renderable};
|
use hypertext::{Raw, Renderable};
|
||||||
use pipeline::{Asset, AssetKind, Content, FileItemKind, Output, OutputKind, PipelineItem};
|
use pipeline::{Asset, AssetKind, Content, FileItemKind, Output, OutputKind, PipelineItem};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use website::WebsiteDesigner;
|
||||||
|
|
||||||
use crate::pipeline::Virtual;
|
use crate::pipeline::Virtual;
|
||||||
|
|
||||||
|
@ -83,41 +86,38 @@ fn main() {
|
||||||
.into(),
|
.into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let sources = &[
|
let website = WebsiteDesigner::default()
|
||||||
Source {
|
.add_source(Source {
|
||||||
path: "content/about.md",
|
path: "content/about.md",
|
||||||
exts: ["md"].into(),
|
exts: ["md"].into(),
|
||||||
func: process_content::<crate::html::Post>,
|
func: process_content::<crate::html::Post>,
|
||||||
},
|
})
|
||||||
Source {
|
.add_source(Source {
|
||||||
path: "content/posts/**/*",
|
path: "content/posts/**/*",
|
||||||
exts: ["md", "mdx"].into(),
|
exts: ["md", "mdx"].into(),
|
||||||
func: process_content::<crate::html::Post>,
|
func: process_content::<crate::html::Post>,
|
||||||
},
|
})
|
||||||
Source {
|
.add_source(Source {
|
||||||
path: "content/slides/**/*",
|
path: "content/slides/**/*",
|
||||||
exts: ["md", "lhs"].into(),
|
exts: ["md", "lhs"].into(),
|
||||||
func: process_content::<crate::html::Slideshow>,
|
func: process_content::<crate::html::Slideshow>,
|
||||||
},
|
})
|
||||||
Source {
|
.add_source(Source {
|
||||||
path: "content/wiki/**/*",
|
path: "content/wiki/**/*",
|
||||||
exts: ["md"].into(),
|
exts: ["md"].into(),
|
||||||
func: process_content::<crate::html::Wiki>,
|
func: process_content::<crate::html::Wiki>,
|
||||||
},
|
})
|
||||||
];
|
.add_output(Output {
|
||||||
|
|
||||||
let special = vec![
|
|
||||||
Output {
|
|
||||||
kind: Virtual::new(|sack| crate::html::map(sack).render().to_owned().into()).into(),
|
kind: Virtual::new(|sack| crate::html::map(sack).render().to_owned().into()).into(),
|
||||||
path: "map/index.html".into(),
|
path: "map/index.html".into(),
|
||||||
link: None,
|
link: None,
|
||||||
},
|
})
|
||||||
Output {
|
.add_output(Output {
|
||||||
kind: Virtual::new(|sack| crate::html::search(sack).render().to_owned().into()).into(),
|
kind: Virtual::new(|sack| crate::html::search(sack).render().to_owned().into()).into(),
|
||||||
path: "search/index.html".into(),
|
path: "search/index.html".into(),
|
||||||
link: None,
|
link: None,
|
||||||
},
|
})
|
||||||
Output {
|
.add_output(Output {
|
||||||
kind: Asset {
|
kind: Asset {
|
||||||
kind: pipeline::AssetKind::html(|sack| {
|
kind: pipeline::AssetKind::html(|sack| {
|
||||||
let data = std::fs::read_to_string("content/index.md").unwrap();
|
let data = std::fs::read_to_string("content/index.md").unwrap();
|
||||||
|
@ -135,16 +135,16 @@ fn main() {
|
||||||
.into(),
|
.into(),
|
||||||
path: "index.html".into(),
|
path: "index.html".into(),
|
||||||
link: None,
|
link: None,
|
||||||
},
|
})
|
||||||
Output {
|
.add_output(Output {
|
||||||
kind: Virtual::new(|sack| {
|
kind: Virtual::new(|sack| {
|
||||||
crate::html::to_list(sack, sack.get_links("posts/**/*.html"), "Posts".into())
|
crate::html::to_list(sack, sack.get_links("posts/**/*.html"), "Posts".into())
|
||||||
})
|
})
|
||||||
.into(),
|
.into(),
|
||||||
path: "posts/index.html".into(),
|
path: "posts/index.html".into(),
|
||||||
link: None,
|
link: None,
|
||||||
},
|
})
|
||||||
Output {
|
.add_output(Output {
|
||||||
kind: Virtual::new(|sack| {
|
kind: Virtual::new(|sack| {
|
||||||
crate::html::to_list(
|
crate::html::to_list(
|
||||||
sack,
|
sack,
|
||||||
|
@ -155,17 +155,12 @@ fn main() {
|
||||||
.into(),
|
.into(),
|
||||||
path: "slides/index.html".into(),
|
path: "slides/index.html".into(),
|
||||||
link: None,
|
link: None,
|
||||||
},
|
})
|
||||||
];
|
.finish();
|
||||||
|
|
||||||
match args.mode {
|
match args.mode {
|
||||||
Mode::Build => {
|
Mode::Build => website.build(&ctx),
|
||||||
let _ = build(&ctx, sources, special);
|
Mode::Watch => website.watch(&ctx),
|
||||||
}
|
|
||||||
Mode::Watch => {
|
|
||||||
let state = build(&ctx, sources, special);
|
|
||||||
watch::watch(&ctx, sources, state).unwrap()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +194,7 @@ impl Source {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build(ctx: &BuildContext, sources: &[Source], special: Vec<Output>) -> Vec<Output> {
|
fn build(ctx: &BuildContext, sources: &[Source], special: &[Rc<Output>]) -> Vec<Rc<Output>> {
|
||||||
crate::build::clean_dist();
|
crate::build::clean_dist();
|
||||||
|
|
||||||
let content: Vec<Output> = sources
|
let content: Vec<Output> = sources
|
||||||
|
@ -220,7 +215,7 @@ fn build(ctx: &BuildContext, sources: &[Source], special: Vec<Output>) -> Vec<Ou
|
||||||
let hashes = crate::build::store_hash_all(&images);
|
let hashes = crate::build::store_hash_all(&images);
|
||||||
let hashes = HashMap::from_iter(hashes.into_iter().map(|Hashed { file, hash }| (file, hash)));
|
let hashes = HashMap::from_iter(hashes.into_iter().map(|Hashed { file, hash }| (file, hash)));
|
||||||
|
|
||||||
let assets: Vec<_> = content.iter().chain(special.iter()).collect();
|
let assets: Vec<_> = content.iter().chain(special.iter().map(AsRef::as_ref)).collect();
|
||||||
|
|
||||||
crate::build::build_content(ctx, &assets, &assets, Some(hashes));
|
crate::build::build_content(ctx, &assets, &assets, Some(hashes));
|
||||||
crate::build::build_static();
|
crate::build::build_static();
|
||||||
|
@ -228,7 +223,7 @@ fn build(ctx: &BuildContext, sources: &[Source], special: Vec<Output>) -> Vec<Ou
|
||||||
crate::build::build_pagefind();
|
crate::build::build_pagefind();
|
||||||
crate::build::build_js();
|
crate::build::build_js();
|
||||||
|
|
||||||
content.into_iter().chain(special).collect()
|
content.into_iter().map(Rc::new).chain(special.iter().map(ToOwned::to_owned)).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_frontmatter<D>(raw: &str) -> (D, String)
|
pub fn parse_frontmatter<D>(raw: &str) -> (D, String)
|
||||||
|
|
|
@ -71,7 +71,7 @@ fn new_thread_ws_reload(
|
||||||
(tx, thread)
|
(tx, thread)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn watch(ctx: &BuildContext, sources: &[Source], state: Vec<Output>) -> Result<()> {
|
pub fn watch(ctx: &BuildContext, sources: &[Source], mut state: Vec<Rc<Output>>) -> Result<()> {
|
||||||
let root = env::current_dir().unwrap();
|
let root = env::current_dir().unwrap();
|
||||||
let server = TcpListener::bind("127.0.0.1:1337")?;
|
let server = TcpListener::bind("127.0.0.1:1337")?;
|
||||||
let client = Arc::new(Mutex::new(vec![]));
|
let client = Arc::new(Mutex::new(vec![]));
|
||||||
|
@ -92,8 +92,6 @@ pub fn watch(ctx: &BuildContext, sources: &[Source], state: Vec<Output>) -> Resu
|
||||||
let thread_i = new_thread_ws_incoming(server, client.clone());
|
let thread_i = new_thread_ws_incoming(server, client.clone());
|
||||||
let (tx_reload, thread_o) = new_thread_ws_reload(client.clone());
|
let (tx_reload, thread_o) = new_thread_ws_reload(client.clone());
|
||||||
|
|
||||||
let mut state: Vec<Rc<Output>> = state.into_iter().map(Rc::new).collect();
|
|
||||||
|
|
||||||
while let Ok(events) = rx.recv().unwrap() {
|
while let Ok(events) = rx.recv().unwrap() {
|
||||||
let paths: Vec<Utf8PathBuf> = events
|
let paths: Vec<Utf8PathBuf> = events
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
49
src/website.rs
Normal file
49
src/website.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use crate::{build, pipeline::Output, watch, BuildContext, Source};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct Website {
|
||||||
|
sources: Vec<Source>,
|
||||||
|
special: Vec<Rc<Output>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Website {
|
||||||
|
pub(crate) fn designer() -> WebsiteDesigner {
|
||||||
|
WebsiteDesigner::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn build(&self, ctx: &BuildContext) {
|
||||||
|
let _ = build(ctx, &self.sources, &self.special.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn watch(&self, ctx: &BuildContext) {
|
||||||
|
let state = build(&ctx, &self.sources, &self.special.clone());
|
||||||
|
watch::watch(&ctx, &self.sources, state).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub(crate) struct WebsiteDesigner {
|
||||||
|
sources: Vec<Source>,
|
||||||
|
special: Vec<Rc<Output>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebsiteDesigner {
|
||||||
|
pub(crate) fn add_source(mut self, source: Source) -> WebsiteDesigner {
|
||||||
|
self.sources.push(source);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn add_output(mut self, output: Output) -> WebsiteDesigner {
|
||||||
|
self.special.push(Rc::new(output));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn finish(self) -> Website {
|
||||||
|
Website {
|
||||||
|
sources: self.sources,
|
||||||
|
special: self.special,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue