Skip to content

Remove the Redirect and Remapped wrapper variants from the Status enum.#2129

Merged
thomas-zahner merged 5 commits intomasterfrom
refactor/phase1-flatten-status
Apr 20, 2026
Merged

Remove the Redirect and Remapped wrapper variants from the Status enum.#2129
thomas-zahner merged 5 commits intomasterfrom
refactor/phase1-flatten-status

Conversation

@mre
Copy link
Copy Markdown
Member

@mre mre commented Apr 4, 2026

The goal of this refactor is to make a step towards cleaning up the Status enum as proposed in #2097.

Previously, redirect and remap information was nested inside the Status enum, which forced every exhaustive match (~8 places) to either recurse through these wrappers or delegate via the innermost() helper. This made the enum harder to work with and obscured the actual status.

The proposal is to have redirect and remap data live as separate fields on ResponseBody.
This gets rid of innermost() and redirects() methods from Status and all is_success/is_error/etc. methods now match directly on self.

I am aware that the three Nones in a row in Response are pretty bad. The constructor already had too many positional params before this change, and I made it worse.

However, this change will unlock the possibility to move redirects into Outcome in the future, e.g.

pub enum Outcome {
    Website {
        result: Result<StatusCode, reqwest::Error>,
        redirects: Redirects,
        fragment_check: Option<bool>,
    },
    // ...
}

This way, we can get rid of the None fields in Response again in the future when we introduce Outcome.

(I attempted that first, but it turned out to be a much bigger refactor, so I broke out a smaller chunk for now.)

…num.

Previously, redirect and remap information was nested inside the Status
enum, which forced every exhaustive match (~8 sites) to either recurse
through these wrappers or delegate via an innermost() helper. This made
the enum harder to work with and obscured the actual status.

Key changes:
- Status enum loses Redirected and Remapped variants (9 variants -> 9)
- Remove innermost() and redirects() methods from Status
- All is_success/is_error/etc. methods now match directly on self
- ResponseBody gains redirects and remap fields
- Response::new() accepts redirects and remap parameters
- WebsiteChecker::check_website() returns (Status, Option<Redirects>)
- RedirectHistory::handle_redirected() replaced with resolve()
- Client::check() passes redirects/remap to Response, not Status
- All exhaustive matches simplified (no more recursive delegation)
- Redirect/remap details now rendered in ResponseBody::Display
@mre mre force-pushed the refactor/phase1-flatten-status branch from dc437e5 to f988413 Compare April 4, 2026 18:17
Comment thread lychee-bin/tests/cli.rs
@mre mre requested review from katrinafyi and thomas-zahner April 7, 2026 09:46
Copy link
Copy Markdown
Member

@katrinafyi katrinafyi left a comment

Choose a reason for hiding this comment

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

Very happy with the refactor and the resulting simplifications. Looks good!

It's not specific to this PR, but I was never clear on the separation between Response and ResponseBody.

In #2097, it was also my intention to store Remap inside Request and then store Request inside Response. With that, we would avoid needing to move all the fields across into Response(Body), like span, source, etc. Nothing needs to change in this PR, but just checking we're on the same page :)

Comment thread lychee-lib/src/types/response.rs Outdated
Comment thread lychee-bin/tests/cli.rs Outdated
@mre
Copy link
Copy Markdown
Member Author

mre commented Apr 7, 2026

In #2097, it was also my intention to store Remap inside Request and then store Request inside Response. With that, we would avoid needing to move all the fields across into Response(Body), like span, source, etc. Nothing needs to change in this PR, but just checking we're on the same page :)

Sounds like a plan. No objections right now. My only concern is that Response becomes quite a big type, so printing might get harder, but inspection should get easier. So it's a tradeoff.

I've never been a huge fan of the standalone ResponseBody anyway. Well, having a strong type instead of Option<String> would be nice, but the fact that ResponseBody was completely detached from Response caused some headaches in the past, like the field-copying/alignment that you mentioned.

@mre mre mentioned this pull request Apr 7, 2026
@katrinafyi
Copy link
Copy Markdown
Member

katrinafyi commented Apr 7, 2026

Yeah, the main use of ResponseBody is it appears in the response maps:

    pub(crate) success_map: HashMap<InputSource, HashSet<ResponseBody>>,

where ResponseBody is basically a Response minus the InputSource.

pub struct Response {
    input_source: InputSource,
    response_body: ResponseBody,
}

This makes some sense, as the hashmap already has the input source in the key. But yeah, just something to keep in mind for later.

Copy link
Copy Markdown
Member

@thomas-zahner thomas-zahner left a comment

Choose a reason for hiding this comment

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

Thank you @mre, I have no objections. I agree that we can clean up the Nones with a new PR as you explained.

Sorry for introducing this confusing approach in the first place. Additionally, the current nesting made it possible to introduce useless and confusing state such as containing Redirected or Remapped multiple times. This is something I didn't think about when I introduced it. So your refactor is definitely the way to go 👍

@mre
Copy link
Copy Markdown
Member Author

mre commented Apr 7, 2026

Cool! I will rebase the PR and apply the changes we agreed on when I get the chance. Will merge when everything is clean.

Comment thread lychee-bin/src/commands/check.rs
As @katrinafyi pointed out this makes more sense since remaps are
applied before redirects are followed.
@mre
Copy link
Copy Markdown
Member Author

mre commented Apr 16, 2026

Just some more lints to fix. 😅 @thomas-zahner, guess you're on it?

@thomas-zahner thomas-zahner merged commit ef5652c into master Apr 20, 2026
12 of 13 checks passed
@thomas-zahner thomas-zahner deleted the refactor/phase1-flatten-status branch April 20, 2026 08:32
@mre mre mentioned this pull request Apr 20, 2026
@mre
Copy link
Copy Markdown
Member Author

mre commented Apr 20, 2026

Thanks for pushing this over the finishing line, Thomas!

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.

3 participants