Skip to content

Commit

Permalink
attr::none
Browse files Browse the repository at this point in the history
fix #12
  • Loading branch information
jcornaz committed Dec 16, 2024
1 parent b4e2563 commit cde262c
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [Unreleased]

### Added

* `attr::none()` for conditional rendering of an attribute
* implement `Default` for `Element` and `Attribute`


## [1.4.0] - 2024-12-13

Expand Down
17 changes: 17 additions & 0 deletions src/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,23 @@ impl<T: Into<Cow<'static, str>>> From<(&'static str, T)> for Attribute {
}
}

/// Do not render any attribute. Useful for conditional rendering.
///
/// # Example
///
/// ```
/// use fun_html::{attr, elt};
///
/// let name: Option<&str> = None;
/// let element = elt::div([
/// // Note, `unwrap_or_default()` would have the same effect here
/// name.map(attr::name).unwrap_or(attr::none()),
/// ], []);
/// ```
pub fn none() -> Attribute {
Attribute(crate::AttributeInner::None)
}

/// `id` attribute
pub fn id(id: impl Into<Cow<'static, str>>) -> Attribute {
Attribute::new("id", id)
Expand Down
25 changes: 21 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ pub struct Document(Element);
///
/// assert_eq!(element.to_string(), "<div></div>");
/// ```
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Default)]
pub struct Element(ElementInner);

#[derive(Debug, Clone)]
Expand All @@ -116,6 +116,12 @@ enum ElementInner {
None,
}

impl Default for ElementInner {
fn default() -> Self {
Self::None
}
}

/// An attribute
///
/// It can be created via [`Self::new`], [`Self::new_flag`]
Expand All @@ -132,14 +138,21 @@ enum ElementInner {
/// r#"id="foo""#,
/// )
/// ```
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Default)]
pub struct Attribute(AttributeInner);

#[derive(Debug, Clone)]
enum AttributeInner {
KeyValue(Cow<'static, str>, Cow<'static, str>),
KeyValueInt(Cow<'static, str>, i32),
Flag(Cow<'static, str>),
None,
}

impl Default for AttributeInner {
fn default() -> Self {
Self::None
}
}

impl Default for Document {
Expand Down Expand Up @@ -237,9 +250,12 @@ impl Display for Element {

fn write_attributes(
f: &mut alloc::fmt::Formatter<'_>,
attributes: &Vec<Attribute>,
attributes: &[Attribute],
) -> Result<(), alloc::fmt::Error> {
for attribute in attributes {
for attribute in attributes
.iter()
.filter(|a| !matches!(&a.0, AttributeInner::None))
{
write!(f, " {attribute}")?;
}
Ok(())
Expand All @@ -260,6 +276,7 @@ impl Display for Attribute {
write!(f, "{key}=\"{value}\"")
}
AttributeInner::Flag(key) => write!(f, "{key}"),
AttributeInner::None => Ok(()),
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions tests/render_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ fn should_render_html_document() {
}

#[rstest]
#[case(attr::none(), "")]
#[case(("foo", "bar").into(), "foo=\"bar\"")]
#[case(("x-on:keyup.enter", "doSomething").into(), "x-on:keyup.enter=\"doSomething\"")]
#[case(("@keyup.enter", "doSomething").into(), "@keyup.enter=\"doSomething\"")]
Expand Down Expand Up @@ -98,6 +99,7 @@ fn should_render_attribute(#[case] attr: Attribute, #[case] expected: &str) {
#[rstest]
#[case(elt::none(), "")]
#[case([elt::div([], []), elt::div([], [])].into(), "<div></div><div></div>")]
#[case(elt::div([attr::none(), attr::none()], []), "<div></div>")]
#[case(elt::div([], elt::div([], [])), "<div><div></div></div>")]
#[case(elt::text("hello"), "hello")]
#[case(elt::text("hello".to_string()), "hello")]
Expand Down

0 comments on commit cde262c

Please sign in to comment.