Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correctly render void elements #38

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 39 additions & 11 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,51 @@ name: Build
on: [push, pull_request]

jobs:
build:
name: ${{ matrix.os }} - ${{ matrix.rust }}
clippy:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
rust: [stable, nightly]
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}
components: clippy
- run: cargo clippy --workspace --no-default-features
- run: cargo clippy --workspace --all-features

fmt:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
rust: [nightly]
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}
components: rustfmt
- run: cargo fmt --all -- --check

test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
rust: [stable, nightly, 1.65.0]
rust: [stable, nightly, '1.65.0']
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}
components: clippy, rustfmt
- run: cargo build
- run: cargo test
- run: cargo test --features itoa
working-directory: markup
- run: cargo fmt -- --check
if: ${{ matrix.os == 'ubuntu-latest' }}
- run: cargo clippy --all-targets
- uses: taiki-e/install-action@v2
with:
tool: cargo-hack
- run: cargo generate-lockfile -Zminimal-versions
env:
RUSTC_BOOTSTRAP: 1
if: ${{ matrix.rust == '1.65.0' }}
- run: cargo hack test --workspace --feature-powerset --optional-deps
3 changes: 1 addition & 2 deletions markup-proc-macro/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ pub struct Element {
pub id: Option<syn::Expr>,
pub classes: Vec<syn::Expr>,
pub attributes: Vec<Attribute>,
pub children: Vec<Node>,
pub close: bool,
pub children: Option<Vec<Node>>,
}

#[derive(Debug)]
Expand Down
11 changes: 5 additions & 6 deletions markup-proc-macro/src/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ impl Generate for Element {
classes,
attributes,
children,
close,
} = self;
stream.raw("<");
stream.expr(name, writer);
Expand Down Expand Up @@ -203,14 +202,14 @@ impl Generate for Element {
}
}

stream.raw(">");

children.generate(stream, writer);

if *close {
if let Some(children) = children {
stream.raw(">");
children.generate(stream, writer);
stream.raw("</");
stream.expr(name, writer);
stream.raw(">");
} else {
stream.raw(" />");
}
}
}
Expand Down
13 changes: 5 additions & 8 deletions markup-proc-macro/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,21 +165,19 @@ impl Parse for Element {
}
};

let (children, close) = {
let children = {
let lookahead = input.lookahead1();
if lookahead.peek(syn::token::Semi) {
let _: syn::Token![;] = input.parse()?;
(Vec::new(), false)
None
} else if lookahead.peek(syn::token::Brace) {
let children;
syn::braced!(children in input);
(children.parse::<Many<_>>()?.0, true)
let Many(children) = children.parse()?;
Some(children)
} else if lookahead.peek(syn::LitStr) {
let string = input.parse::<syn::LitStr>()?;
(
vec![syn::parse_quote_spanned!(string.span() => #string)],
true,
)
Some(vec![syn::parse_quote_spanned!(string.span() => #string)])
} else {
return Err(lookahead.error());
}
Expand All @@ -191,7 +189,6 @@ impl Parse for Element {
classes,
attributes,
children,
close,
})
}
}
Expand Down
6 changes: 4 additions & 2 deletions markup/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ impl<T: std::fmt::Display> Render for Raw<T> {
impl<T: std::fmt::Display> RenderAttributeValue for Raw<T> {}

#[inline]
pub fn raw(value: impl std::fmt::Display) -> impl Render + RenderAttributeValue {
pub fn raw(value: impl std::fmt::Display) -> impl RenderAttributeValue {
Raw(value)
}

Expand Down Expand Up @@ -222,8 +222,10 @@ tuple_impl! { A B C D E F G H }
tuple_impl! { A B C D E F G H I }
tuple_impl! { A B C D E F G H I J }

pub type RenderFn<'a> = dyn Fn(&mut dyn std::fmt::Write) -> std::fmt::Result + 'a;

pub struct DynRender<'a> {
f: Box<dyn Fn(&mut dyn std::fmt::Write) -> std::fmt::Result + 'a>,
f: Box<RenderFn<'a>>,
}

pub fn new<'a, F>(f: F) -> DynRender<'a>
Expand Down
12 changes: 6 additions & 6 deletions markup/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ t! {
br;
}
},
A {} => "<div></div><br>",
A {} => "<div></div><br />",
}

t! {
Expand Down Expand Up @@ -100,7 +100,7 @@ t! {
}
},
A {} => r#"<foo id="bar"><baz id="foo" class="quux 1 5"></baz><bar id="4" class="-1">7</bar></foo>"#,
B {} => r#"<foo>bar</foo><foo id="bar">baz</foo><foo class="bar" baz>quux</foo><foo class="bar" baz>quux"#,
B {} => r#"<foo>bar</foo><foo id="bar">baz</foo><foo class="bar" baz>quux</foo><foo class="bar" baz />quux"#,
C {} => r#"<foo fn mod move></foo>"#,
}

Expand Down Expand Up @@ -132,7 +132,7 @@ t! {
br[k = 6];
}
},
A {} => r#"<div a="1" b="2" c c2 c3 c4 e-f="3" g-h="4" j="5" j2="5" j3="5" h="678truefalse" i="foo"></div><br k="6">"#,
A {} => r#"<div a="1" b="2" c c2 c3 c4 e-f="3" g-h="4" j="5" j2="5" j3="5" h="678truefalse" i="foo"></div><br k="6" />"#,
}

t! {
Expand Down Expand Up @@ -338,8 +338,8 @@ t! {
${name} {}
}
},
A {} => r#"<foo-bar><foo-bar></foo-bar><foo-bar baz="quux"></foo-bar>"#,
B { name: "foo-bar" } => r#"<foo-bar><foo-bar></foo-bar>"#,
A {} => r#"<foo-bar /><foo-bar></foo-bar><foo-bar baz="quux"></foo-bar>"#,
B { name: "foo-bar" } => r#"<foo-bar /><foo-bar></foo-bar>"#,
}

mod inner {
Expand All @@ -358,7 +358,7 @@ t! {
t15,
{
A() {
@for | Ok(x) | Err(x) in vec![Ok(1), Err(2), Ok(3)] {
@for | Ok(x) | Err(x) in [Ok(1), Err(2), Ok(3)] {
@x
}
}
Expand Down
16 changes: 16 additions & 0 deletions ui-tests/fail-1.78/not-render.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
struct NotRender;

markup::define! {
Layout(name: NotRender) {
@markup::doctype()
html["attr-user"=name] {
body {
strong { "Hello " @name "!" }
}
}
}
}

fn main() {

}
35 changes: 35 additions & 0 deletions ui-tests/fail-1.78/not-render.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
error[E0277]: the trait bound `NotRender: RenderAttributeValue` is not satisfied
--> fail-1.78/not-render.rs:6:26
|
6 | html["attr-user"=name] {
| ^^^^ the trait `RenderAttributeValue` is not implemented for `NotRender`, which is required by `&NotRender: RenderAttributeValue`
|
= help: the following other types implement trait `RenderAttributeValue`:
bool
char
isize
i8
i16
i32
i64
i128
and $N others
= note: required for `&NotRender` to implement `RenderAttributeValue`

error[E0277]: the trait bound `NotRender: Render` is not satisfied
--> fail-1.78/not-render.rs:8:36
|
8 | strong { "Hello " @name "!" }
| ^^^^ the trait `Render` is not implemented for `NotRender`, which is required by `&NotRender: Render`
|
= help: the following other types implement trait `Render`:
bool
char
isize
i8
i16
i32
i64
i128
and $N others
= note: required for `&NotRender` to implement `Render`
4 changes: 3 additions & 1 deletion ui-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ fn ui() {
let fail = trybuild::TestCases::new();
if version.minor <= 65 {
fail.compile_fail("fail-1.65/*.rs");
} else {
} else if version.minor <= 77 {
fail.compile_fail("fail-1.72/*.rs");
} else {
fail.compile_fail("fail-1.78/*.rs");
}
}
Loading