Skip to content
/ Harper Public

Commit 34954dd

Browse files
committed
Harper + Mockingbird 0.0.2.
This release includes the following major changes: * `derive_more` was removed as a dependency. * Collections are now associated with a name. * Internal refactor for a new `OwnedEntry`. * Updated to minijinja2. * Undefined variables now result in errors. * Added a `get()` template helper with a default when undefined. * Added a real CLI parser. * Added a `time!()` macro for wall-clock time measurements. * Now exits with status 1 if rendering fails.
1 parent a40f5fd commit 34954dd

28 files changed

+343
-311
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# Version 0.0.2 (Apr 4, 2024)
2+
3+
This is the second testing release of Mockingbird. More details to come.
4+
15
# Version 0.0.1 (Mar 3, 2024)
26

37
This is the initial testing release of Mockingbird. More details to come.

lib/Cargo.toml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "harper"
3-
version = "0.0.1"
3+
version = "0.0.2"
44
edition = "2021"
55
authors = ["Sergio Benitez <sb@sergio.bz>"]
66
license = "MIT OR Apache-2.0"
@@ -23,7 +23,6 @@ serde = { version = "1", features = ["rc", "derive"] }
2323
toml = { version = "0.8", features = ["preserve_order"] }
2424
memchr = "2"
2525
either = "1.10"
26-
derive_more = { version = "=1.0.0-beta.6", features = ["debug", "deref", "from"] }
2726
grass = { version = "0.13", default-features = false, features = ["random"], optional = true }
2827
pulldown-cmark = { version = "0.10", default-features = false, features = ["simd", "html"] }
2928

@@ -56,11 +55,8 @@ default-features = false
5655
features = ["html", "default-syntaxes", "regex-onig", "plist-load"]
5756

5857
[dependencies.minijinja]
59-
# git = "https://github.com/SergioBenitez/minijinja.git"
60-
# # branch = "value-unification"
61-
# rev = "517d147"
6258
package = "unified-minijinja"
63-
version = "1.0.12"
59+
version = "=0.0.2"
6460
default-features = false
6561
features = ["speedups", "loader", "builtins", "debug", "deserialization", "macros", "multi_template"]
6662

lib/src/fstree.rs

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
1+
use std::{fs, fmt};
2+
use std::ops::Deref;
13
use std::sync::Arc;
24
use std::path::Path;
35
use std::collections::VecDeque;
4-
use std::{fs, fmt};
56

67
use rustc_hash::FxHashMap;
78

89
use crate::error::Result;
910

10-
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
11-
pub struct EntryId(pub(crate) usize);
12-
1311
#[derive(Debug)]
1412
pub struct FsTree {
1513
entries: Vec<Entry>,
1614
map: FxHashMap<Arc<Path>, EntryId>,
1715
}
1816

19-
pub struct FsSubTree<'a> {
20-
tree: &'a FsTree,
21-
root: EntryId
17+
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
18+
pub struct EntryId(usize);
19+
20+
#[derive(Clone)]
21+
pub struct OwnedEntry {
22+
pub tree: Arc<FsTree>,
23+
pub id: EntryId,
2224
}
2325

2426
#[derive(Debug)]
@@ -44,10 +46,12 @@ impl FsTree {
4446
}
4547
}
4648

49+
#[inline(always)]
4750
pub fn build<P: AsRef<Path>>(root: P) -> Result<Self> {
4851
Self::build_with(root.as_ref(), |_, _| Ok(()))
4952
}
5053

54+
#[inline]
5155
pub fn build_with<P, F>(root: P, mut callback: F) -> Result<Self>
5256
where P: AsRef<Path>,
5357
F: FnMut(&Self, EntryId) -> Result<()>,
@@ -91,12 +95,6 @@ impl FsTree {
9195
EntryId(0)
9296
}
9397

94-
#[inline]
95-
pub fn subtree(&self, root: EntryId) -> FsSubTree<'_> {
96-
assert!(self[root].id == root);
97-
FsSubTree { tree: self, root }
98-
}
99-
10098
#[inline]
10199
pub fn get<R, P>(&self, root: R, path: P) -> Option<&Entry>
102100
where R: Into<Option<EntryId>>, P: AsRef<Path>
@@ -227,22 +225,38 @@ impl FsTree {
227225
}
228226
}
229227

230-
impl FsSubTree<'_> {
231-
pub fn get<P: AsRef<Path>>(&self, path: P) -> Option<&Entry> {
232-
self.tree.get(self.root, path.as_ref())
228+
impl OwnedEntry {
229+
pub fn new(tree: Arc<FsTree>, id: EntryId) -> Self {
230+
OwnedEntry { tree, id }
233231
}
234232

235-
#[inline]
236-
pub fn get_file_id<P: AsRef<Path>>(&self, path: P) -> Option<EntryId> {
237-
self.tree.get_file_id(self.root, path.as_ref())
233+
pub fn entry(&self) -> &Entry {
234+
&self.tree[self.id]
238235
}
236+
}
239237

240-
#[inline]
241-
pub fn get_id<P: AsRef<Path>>(&self, path: P) -> Option<EntryId> {
242-
self.tree.get_id(self.root, path.as_ref())
238+
impl Deref for OwnedEntry {
239+
type Target = Entry;
240+
241+
fn deref(&self) -> &Self::Target {
242+
self.entry()
243+
}
244+
}
245+
246+
impl fmt::Debug for OwnedEntry {
247+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
248+
self.entry().fmt(f)
249+
}
250+
}
251+
252+
impl PartialEq for OwnedEntry {
253+
fn eq(&self, other: &Self) -> bool {
254+
self.id == other.id
243255
}
244256
}
245257

258+
impl Eq for OwnedEntry { }
259+
246260
impl Entry {
247261
/// File name without the extension.
248262
pub fn file_stem(&self) -> &str {

lib/src/markdown/alias.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ impl<'a> Alias<'a> {
1919
}
2020

2121
impl crate::markdown::Plugin for Alias<'_> {
22-
fn remap<'a, I>(&'a mut self, events: I) -> Box<dyn Iterator<Item = Event<'a>> + 'a>
22+
fn remap<'a, I>(&'a mut self, events: I) -> impl Iterator<Item = Event<'a>> + 'a
2323
where I: Iterator<Item = Event<'a>> + 'a
2424
{
25-
Box::new(AliasIterator { inner: events, map: self.map })
25+
AliasIterator { inner: events, map: self.map }
2626
}
2727
}
2828

lib/src/markdown/auto_heading.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,14 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for HeadingIterator<'a, I> {
5454
}
5555

5656
impl Plugin for AutoHeading {
57-
fn remap<'a, I>(&'a mut self, events: I) -> Box<dyn Iterator<Item = Event<'a>> + 'a>
57+
fn remap<'a, I>(&'a mut self, events: I) -> impl Iterator<Item = Event<'a>> + 'a
5858
where I: Iterator<Item = Event<'a>> + 'a
5959
{
60-
Box::new(HeadingIterator {
60+
HeadingIterator {
6161
seen: FxHashMap::default(),
6262
inner: events,
6363
stack: VecDeque::with_capacity(4),
64-
})
64+
}
6565
}
6666
}
6767

@@ -92,12 +92,12 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for AnchorIterator<'a, I> {
9292
}
9393

9494
impl Plugin for HeadingAnchor {
95-
fn remap<'a, I>(&'a mut self, events: I) -> Box<dyn Iterator<Item = Event<'a>> + 'a>
95+
fn remap<'a, I>(&'a mut self, events: I) -> impl Iterator<Item = Event<'a>> + 'a
9696
where I: Iterator<Item = Event<'a>> + 'a
9797
{
98-
Box::new(AnchorIterator {
98+
AnchorIterator {
9999
inner: events,
100100
pending: None,
101-
})
101+
}
102102
}
103103
}

lib/src/markdown/code_filter.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ impl CodeTrim<()> {
4040
}
4141

4242
impl<F: CodeFilter> Plugin for CodeTrim<F> {
43-
fn remap<'a, I>(&'a mut self, i: I) -> Box<dyn Iterator<Item = Event<'a>> + 'a>
43+
fn remap<'a, I>(&'a mut self, i: I) -> impl Iterator<Item = Event<'a>> + 'a
4444
where I: Iterator<Item = Event<'a>> + 'a
4545
{
46-
Box::new(Iter {
46+
Iter {
4747
trimmer: &mut self.trimmer,
4848
inner: i,
4949
line_num: None,
5050
stack: VecDeque::new(),
51-
})
51+
}
5252
}
5353
}
5454

lib/src/markdown/highlight.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ impl SyntaxHighlight {
3131
}
3232

3333
impl Plugin for SyntaxHighlight {
34-
fn remap<'a, I>(&'a mut self, events: I) -> Box<dyn Iterator<Item = Event<'a>> + 'a>
34+
fn remap<'a, I>(&'a mut self, events: I) -> impl Iterator<Item = Event<'a>> + 'a
3535
where I: Iterator<Item = Event<'a>> + 'a
3636
{
37-
Box::new(Highlighter { generator: None, lines: 0, inner: events })
37+
Highlighter { generator: None, lines: 0, inner: events }
3838
}
3939
}
4040

lib/src/markdown/parts.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ impl<O: Sink> Plugin for Parts<O> {
5555
// secion. This causes the HTML renderer to emit the string so far. We then
5656
// reuse the same iterator in the renderer again until it signals it cannot
5757
// be reused. We finally return one string containing all of the HTML.
58-
fn remap<'a, I>(&'a mut self, events: I) -> Box<dyn Iterator<Item = Event<'a>> + 'a>
58+
fn remap<'a, I>(&'a mut self, events: I) -> impl Iterator<Item = Event<'a>> + 'a
5959
where I: Iterator<Item = Event<'a>> + 'a
6060
{
6161
let mut sections = SectionIterator {
@@ -84,7 +84,7 @@ impl<O: Sink> Plugin for Parts<O> {
8484
_ => self.sections.join("").into(),
8585
};
8686

87-
Box::new(Some(Event::Html(complete_html)).into_iter())
87+
Some(Event::Html(complete_html)).into_iter()
8888
}
8989

9090
fn finalize(&mut self) -> Result<()> {

lib/src/markdown/plugin.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,11 @@ pub trait Plugin {
1010
Ok(Cow::Borrowed(input))
1111
}
1212

13-
// FIXME: To get rid of this box, we need (ideally) `-> impl Trait` in trait
14-
// methods, or generic associated types. Edit: We now have GATs! But they're
15-
// incredibly annoying to use because of the required bounds everywhere.
1613
#[inline(always)]
17-
fn remap<'a, I>(&'a mut self, events: I) -> Box<dyn Iterator<Item = Event<'a>> + 'a>
14+
fn remap<'a, I>(&'a mut self, events: I) -> impl Iterator<Item = Event<'a>> + 'a
1815
where I: Iterator<Item = Event<'a>> + 'a
1916
{
20-
Box::new(events)
17+
events
2118
}
2219

2320
#[inline(always)]

lib/src/markdown/render.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,16 @@ impl<O: Sink> Renderer<O> {
1717
}
1818

1919
impl<O: Sink> Plugin for Renderer<O> {
20-
fn remap<'a, I>(&'a mut self, events: I) -> Box<dyn Iterator<Item = Event<'a>> + 'a>
20+
fn remap<'a, I>(&'a mut self, events: I) -> impl Iterator<Item = Event<'a>> + 'a
2121
where I: Iterator<Item = Event<'a>>
2222
{
2323
let mut html_output = String::new();
2424
html::push_html(&mut html_output, events);
2525
self.rendered = html_output;
26-
Box::new(std::iter::empty())
26+
std::iter::empty()
2727
}
2828

2929
fn finalize(&mut self) -> Result<()> {
30-
let string = std::mem::replace(&mut self.rendered, String::new());
31-
self.output.write(string)
30+
self.output.write(std::mem::take(&mut self.rendered))
3231
}
3332
}

0 commit comments

Comments
 (0)