Skip to content

Implement IntoIterator for GlobSetBuilder #3025

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

Closed

Conversation

squidfunk
Copy link

Originally reported here: BurntSushi/globset#8

This PR fixes the linked issue. See below:


The Debug implementation of GlobSetBuilder is quite noisy. For better introspectability in consuming packages, it would be perfect if one of two things could be implemented, so the Debug implementation can be adjusted (favorite) or is more readable:

  1. An IntoIterator<Item = &Glob> implementation for &GlobSetBuilder, so we can use the Display implementation of Glob where applicable. This would be a non-invasive addition, as the consumer can decide what style they want.
  2. A Debug implementation for GlobSetBuilder that does 1., i.e., prints Glob via Display.

I'm happy to send a PR for either of which, if this is a good match.

Example

#[cfg(test)]
mod tests {
    use globset::{Glob, GlobSetBuilder};

    #[test]
    fn test() -> Result<(), Box<dyn std::error::Error>> {
        let mut builder = GlobSetBuilder::new();
        builder.add(Glob::new("src/**/*.rs")?);
        builder.add(Glob::new("*.txt")?);
        builder.add(Glob::new("docs/**/*.md")?);
        println!("{:#?}", builder);
        Ok(())
    }
}

Current Result

GlobSetBuilder {
    pats: [
        Glob {
            glob: "src/**/*.rs",
            re: "(?-u)^src(?:/|/.*/).*\\.rs$",
            opts: GlobOptions {
                case_insensitive: false,
                literal_separator: false,
                backslash_escape: true,
            },
            tokens: Tokens(
                [
                    Literal(
                        's',
                    ),
                    Literal(
                        'r',
                    ),
                    Literal(
                        'c',
                    ),
                    RecursiveZeroOrMore,
                    ZeroOrMore,
                    Literal(
                        '.',
                    ),
                    Literal(
                        'r',
                    ),
                    Literal(
                        's',
                    ),
                ],
            ),
        },
        Glob {
            glob: "*.txt",
            re: "(?-u)^.*\\.txt$",
            opts: GlobOptions {
                case_insensitive: false,
                literal_separator: false,
                backslash_escape: true,
            },
            tokens: Tokens(
                [
                    ZeroOrMore,
                    Literal(
                        '.',
                    ),
                    Literal(
                        't',
                    ),
                    Literal(
                        'x',
                    ),
                    Literal(
                        't',
                    ),
                ],
            ),
        },
        Glob {
            glob: "docs/**/*.md",
            re: "(?-u)^docs(?:/|/.*/).*\\.md$",
            opts: GlobOptions {
                case_insensitive: false,
                literal_separator: false,
                backslash_escape: true,
            },
            tokens: Tokens(
                [
                    Literal(
                        'd',
                    ),
                    Literal(
                        'o',
                    ),
                    Literal(
                        'c',
                    ),
                    Literal(
                        's',
                    ),
                    RecursiveZeroOrMore,
                    ZeroOrMore,
                    Literal(
                        '.',
                    ),
                    Literal(
                        'm',
                    ),
                    Literal(
                        'd',
                    ),
                ],
            ),
        },
    ],
}

Ideal Result:

GlobSetBuilder {
    pats: [
        "src/**/*.rs",
        "*.txt",
        "docs/**/*.md",
    ]
}

Oh and thanks for this library, it is awesome!

@BurntSushi
Copy link
Owner

Oh hmmm, I think I might have misread your original issue. I was thinking that we'd just make the Debug impl smaller without exposing new APIs.

@squidfunk
Copy link
Author

No problem, so something like this maybe?

impl std::fmt::Debug for GlobSetBuilder {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let pats = self.pats.iter().map(ToString::to_string).collect::<Vec<_>>();
        f.debug_struct("GlobSetBuilder").field("pats", &pats).finish()
    }
}

Output:

GlobSetBuilder {
    pats: [
        "foo",
        "bar",
    ],
}

Or would you want to change the debug impl of Glob? I though that maybe that's not what you wanted, given that inspecting globs might be another use case than inspecting a glob set.

@BurntSushi
Copy link
Owner

That looks fine to me. But you'll want to branch on f.alternate().

@squidfunk
Copy link
Author

Okay, I hope I understand you correctly:

impl std::fmt::Debug for GlobSetBuilder {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        if f.alternate() {
            f.debug_struct("GlobSetBuilder").field("pats", &self.pats).finish()
        // Print the patterns in a way that is easy to read.
        } else {
            let pats = self.pats.iter().map(ToString::to_string).collect::<Vec<_>>();
            f.debug_struct("GlobSetBuilder").field("pats", &pats).finish()
        }
    }
}

If that's fine, I can send another PR.

@squidfunk
Copy link
Author

Superseded by #3026.

@squidfunk squidfunk closed this Apr 9, 2025
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