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

feat(mrml-core): add Fragment element #437

Closed
wants to merge 5 commits into from

Conversation

JadedBlueEyes
Copy link
Contributor

This component effectively just acts as a collection of children. However, when rendered, they behave as if directly under the parent element. This is useful for passing around reusable components, etc, in Rust code.

Right now, it is not actually possible to parse a Fragment. Instead, they must be constructed by Rust code. This is because of some non-configurable validation in xmlparser:
https://github.com/RazrFalcon/xmlparser/blob/e54c2768f20814140c11e6c92f94ee74bfd54808/src/stream.rs#L432

I'm using this in mrmx, as it makes it quite a bit more pleasant to use.

This might have a slight performance impact, as fn get_children allocates a Vector to help fold all children and nested Fragment children into one array. Before, this was directly calling .iter() on self.element.children. However, local benchmarking doesn't find any significant difference. I'm very much open to a different solution, though!


     Running benches/basic.rs (C:\Users\jade\.cache\cargo-target\release\deps\basic-9ef9e838d0ba5c55.exe)
Benchmarking render button: Collecting 100 samples in estimated 5.0707 s 
                        time:   [16.882 µs 17.014 µs 17.161 µs]
                        change: [-3.1318% -0.5849% +1.9841%] (p = 0.66 > 0.05)
                        No change in performance detected.
Found 7 outliers among 100 measurements (7.00%)
  5 (5.00%) high mild
  2 (2.00%) high severe

     Running benches/template.rs (C:\Users\jade\.cache\cargo-target\release\deps\template-7a43bc935c493ad3.exe)
Benchmarking amario: Collecting 100 samples in estimated 5.4222 s (10k itera
                        time:   [525.70 µs 529.71 µs 534.01 µs]
                        change: [-3.9368% -1.2313% +1.1003%] (p = 0.37 > 0.05)
                        No change in performance detected.
Found 6 outliers among 100 measurements (6.00%)
  3 (3.00%) high mild
  3 (3.00%) high severe

@JadedBlueEyes JadedBlueEyes changed the title feat(mrmx-core): Add Fragment element feat(mrml-core): Add Fragment element Jun 19, 2024
@JadedBlueEyes JadedBlueEyes changed the title feat(mrml-core): Add Fragment element feat(mrml-core): add Fragment element Jun 19, 2024
Copy link
Owner

@jdrouet jdrouet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👋 Thanks for your interest for mrml and for this first PR!
That's a good react-like idea and I see how it could be used.
First, considering it's not mjml compatible, if this gets merged at some point, it should be behind a feature flag, disabled by default.
Then, we have to find an alternative for this fn children(&self) -> Vec<_>. Rebuilding a Vec is not acceptable.
Finally, we have to put in place some integration tests with some component that are using siblings, raw_siblings, indexes, etc.

packages/mrml-core/src/mj_accordion/render.rs Outdated Show resolved Hide resolved
packages/mrml-core/src/mj_body/render.rs Outdated Show resolved Hide resolved
packages/mrml-core/src/mj_carousel/render.rs Outdated Show resolved Hide resolved
packages/mrml-core/src/mj_carousel/render.rs Outdated Show resolved Hide resolved
packages/mrml-core/src/mj_carousel/render.rs Outdated Show resolved Hide resolved
packages/mrml-core/src/mj_column/render.rs Outdated Show resolved Hide resolved
@jdrouet
Copy link
Owner

jdrouet commented Jun 25, 2024

Moving your PR to draft considering the amount of commented code and the points mentioned.

@jdrouet jdrouet marked this pull request as draft June 25, 2024 16:42
@JadedBlueEyes JadedBlueEyes force-pushed the jade/fragment branch 4 times, most recently from 3fb0081 to 726ef4e Compare June 27, 2024 15:52
Copy link

codecov bot commented Jun 27, 2024

Codecov Report

Attention: Patch coverage is 74.18398% with 87 lines in your changes missing coverage. Please review.

Project coverage is 92.74%. Comparing base (5311e58) to head (726ef4e).
Report is 61 commits behind head on main.

Current head 726ef4e differs from pull request most recent head e67713a

Please upload reports for the commit e67713a to get more accurate results.

Files Patch % Lines
packages/mrml-core/src/fragment/render.rs 32.20% 40 Missing ⚠️
packages/mrml-core/src/fragment/parse.rs 0.00% 20 Missing ⚠️
packages/mrml-core/src/fragment/print.rs 0.00% 15 Missing ⚠️
packages/mrml-core/src/mj_body/children.rs 0.00% 2 Missing ⚠️
packages/mrml-core/src/mj_accordion/render.rs 92.30% 1 Missing ⚠️
packages/mrml-core/src/mj_carousel/render.rs 94.73% 1 Missing ⚠️
packages/mrml-core/src/mj_head/mod.rs 94.44% 1 Missing ⚠️
packages/mrml-core/src/mj_include/body/parse.rs 80.00% 1 Missing ⚠️
packages/mrml-core/src/mj_include/body/render.rs 92.85% 1 Missing ⚠️
packages/mrml-core/src/mj_include/head/parse.rs 83.33% 1 Missing ⚠️
... and 4 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #437      +/-   ##
==========================================
- Coverage   92.89%   92.74%   -0.15%     
==========================================
  Files         227      227              
  Lines       12203    13153     +950     
==========================================
+ Hits        11336    12199     +863     
- Misses        867      954      +87     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

packages/mrml-core/src/mj_carousel/render.rs Outdated Show resolved Hide resolved
@@ -8,6 +9,22 @@ struct MjColumnExtra<'a> {
}

impl<'root> Renderer<'root, MjColumn, MjColumnExtra<'root>> {
#[cfg(feature = "fragment")]
fn children_iter(&self) -> impl Iterator<Item = &MjBodyChild> {
fn folder<'root>(c: &'root MjBodyChild) -> Box<dyn Iterator<Item = &MjBodyChild> + 'root> {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about that but we might not have to go through a Box.
Also, I'm not a big fan of having the function declared like this, just to use it once after.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps a trait would be better? The problem I had with that is that the default impl in a trait can't access fields on a struct, so I have to reimplement the function anyway

This component effectively just acts as a collection of children.
However, when rendered, they behave as if directly under the
parent element. This is useful for passing around reusable
components, etc, in Rust code.

In this commit, it is not actually possible to parse a
Fragment. Instead, they must be constructed by Rust code.
This is because of some non-configurable validation in
xmlparser:
https://github.com/RazrFalcon/xmlparser/blob/e54c2768f20814140c11e6c92f94ee74bfd54808/src/stream.rs#L432

Signed-off-by: Jade Ellis <[email protected]>
@jdrouet
Copy link
Owner

jdrouet commented Oct 22, 2024

This has been stuck for a while now, closing it

@jdrouet jdrouet closed this Oct 22, 2024
@JadedBlueEyes
Copy link
Contributor Author

Hey @jdrouet - Sorry about the lack of communication here. I'm still interested in merging this, and I'd added improvements based on your suggestions, along with some tests. Are there any particular things you'd like to help move this along?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants