-
-
Notifications
You must be signed in to change notification settings - Fork 149
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
Refactor html output functions #529
Conversation
Went a little nuts today 😬 |
Run on Wed Feb 5 01:40:02 UTC 2025 |
I was trying to keep the function signature the same (always the same args) for all the |
D'oh! Maybe we should think about an MSRV bumping policy? Right now we're sitting at 1.62.1 maybe forever, whereas some people out there are using N-2 (!).
The advantage that sticks out in my head is they become more amenable to generated (macro) code; we can't inspect the target function signatures at runtime, but if they all share a signature it'd be possible to do some kind of programmatically generated dispatch! |
That's kind of what I was thinking, maybe setting us up for that possibility.
I think you're right. I'm not sure what exactly the policy should be. One part it's nice not to require a version that's too bleeding edge, so that larger organizations don't need to upgrade their rust version as quickly. For example GitLab is still on 1.73. But we also don't want to completely limit ourselves on the ability to use certain features. Maybe it makes sense, for now, to evaluate when we run into something like the |
I've gone ahead and added a commit to bump the MSRV to I could rewrite the code to not use the wdyt? 🤔 |
Hey @kivikakk. So I've made the https://gitlab.com/gitlab-org/ruby/gems/gitlab-glfm-markdown/-/merge_requests/76/diffs?commit_id=eb78621bfe8f47b6a41652c68ed2e95d5cfc0883 is a hacked together way in which it might be used. I made all the So maybe I wouldn't need to make all those public. This relates to the discussion we had on this topic. I admit I posed the question to an AI and it lead me to this
// Original crate
struct OriginalType;
impl OriginalType {
fn method(&self) {
println!("Original method");
}
}
// Your code
trait ExtendedBehavior {
fn method(&self);
}
impl ExtendedBehavior for OriginalType {
fn method(&self) {
println!("Extended method");
}
}
fn main() {
let obj = OriginalType;
obj.method(); // Prints: "Original method"
ExtendedBehavior::method(&obj); // Prints: "Extended method"
} So I basically used a wrapper type in my hacked attempt. |
I'm happy with making one or all the renderer functions public, tbh! But maybe better to just do the main one (so fewer changes are "breaking").
Yes, indeed; same goes for distro package maintainers.
Works for me! :) |
4930706
to
7336534
Compare
Ok, I know better than this - always keep PRs as small as possible. So this just has the refactoring of the render functions. In another PR I will attempt to make |
This allows us to use the `let...else` style syntax
7336534
to
545419e
Compare
@@ -400,7 +400,7 @@ where | |||
plain | |||
} else { | |||
stack.push((node, false, Phase::Post)); | |||
self.format_node(node, true)? | |||
!self.format_node(node, true)? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an interesting change; can you elaborate on it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Also, to be clear, if it's a mistaken change, then the real mistake is that no test failure resulted from it! And if it isn't, we should add a regression test! Either way it's interesting.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah sorry, I meant to comment on that change.
All the new render_
functions return a io::Result<bool>
, and return an Ok(true)
when the function is successful. The only render function that can return an Ok(false)
is render_image
. And that false
needs to trigger some additional work, just like it did before.
Originally format_node
was returning Ok(false)
by default, which would set new_plain
in format
.
But with the render functions returning a true
for success, then it made more sense to set a processing_complete
boolean with value of the render functions, and return that. So now we had to negate the return value in the line above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests do fail pretty spectacularly if the !
is removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, got it; I misread the diff and thought the true
s and false
s hadn't in fact switched positions. I might change those to a binary enum that actually make clear what work they're doing.
You may again wish to consider the approach I outlined in the discussion: #454 (reply in thread); with an exposed |
Yeah that would be great. I haven't done anything with macros in Rust, and didn't quite follow what you were suggesting at the time. |
Will do in a bit, then. |
I have pushed an example of what I mean here: https://github.com/kivikakk/comrak/compare/custom-html-formatter?w=1 See the added test for a sample use. I'm extremely low on cycles and I basically hacked this together in the fastest way possible to demonstrate the idea. There's a lot of cleanup that can be done; I'm exposing a whole bunch of things here which it'd be nicer not to expose. I am 100% sure this can be done cleaner, and I wouldn't want to merge this as-is — it's just to give you an idea of how a macro could help produce the outcome you want. Note how the baseline |
Oh awesome, thanks! I'll look it over in the next few days |
Refactored the html formatter to handle each node via a separate functions.