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

fix(builder)!: Accept a more liberal Iterator #2857

Closed
wants to merge 1 commit into from

Conversation

epage
Copy link
Member

@epage epage commented Oct 12, 2021

This replaces the most common uses of &[] with IntoIterator.

This is based on #2414. Unlike that, this stays consistent with using
Into<&'help str>.

There are some remaining functions not converted over, like defaults and
requires.

BREAKING CHANGE: Instances like aliases(&[]) need to switch to
aliases([]).

This replaces the most common uses of `&[]` with `IntoIterator`.

This is based on clap-rs#2414.  Unlike that, this stays consistent with using
`Into<&'help str>`.

There are some remaining functions not converted over, like defaults and
requires.

BREAKING CHANGE: Instances like `aliases(&[])` need to switch to
`aliases([])`.
@epage
Copy link
Member Author

epage commented Oct 12, 2021

This worth it for 3.0? What more functions would we need to convert over for this to be considered "done"

Copy link
Member

@pksunkara pksunkara left a comment

Choose a reason for hiding this comment

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

Just one comment.

@@ -2588,8 +2604,12 @@ impl<'help> Arg<'help> {
/// [`Arg::number_of_values`]: Arg::number_of_values()
/// [`Arg::takes_value(true)`]: Arg::takes_value()
/// [`Arg::multiple_values(true)`]: Arg::multiple_values()
pub fn value_names(mut self, names: &[&'help str]) -> Self {
self.val_names = names.to_vec();
pub fn value_names<I>(mut self, names: I) -> Self
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
pub fn value_names<I>(mut self, names: I) -> Self
pub fn value_names<I, T>(mut self, names: I) -> Self

Copy link
Member Author

Choose a reason for hiding this comment

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

I was generally aiming to be consistent with what the non-iterator versions accepted. In this case, value_name accepts a &str.

We can change that if we want.

@pksunkara
Copy link
Member

BREAKING CHANGE: Instances like aliases(&[]) need to switch to
aliases([]).

I thought this wasn't needed. I guess that is why #2414 introduced AsRef<str> IIUC

@epage
Copy link
Member Author

epage commented Oct 12, 2021

BREAKING CHANGE: Instances like aliases(&[]) need to switch to
aliases([]).

I thought this wasn't needed. I guess that is why #2414 introduced AsRef<str> IIUC

More so I think its because it did &T rather than T.

    where
        I: IntoIterator<Item = &'help T>,
        T: AsRef<str> + 'help,

@epage
Copy link
Member Author

epage commented Oct 12, 2021

Looks like that wasn't needed and this can work

Going to go do a PR to switch Into<&str> to AsRef in prep for this one

@pksunkara
Copy link
Member

Do we need lifetime in that AsRef version? I don't see it in the second snippet.

@epage
Copy link
Member Author

epage commented Oct 12, 2021

Bad news is we can't control the lifetime for AsRef so it won't work. In 4.0 when we re-evaluate our string type, this might be easier

@pksunkara
Copy link
Member

pksunkara commented Oct 12, 2021

Wouldn't the following work?

    where
        I: IntoIterator<Item = T>,
        T: AsRef<str> + 'help,

@epage
Copy link
Member Author

epage commented Oct 12, 2021

That can work but what I was looking at was how to be consistent between singular and iterator functions. If we don't care about consistency, that is fine.

@pksunkara
Copy link
Member

I was looking at was how to be consistent between singular and iterator functions.

I am not sure what you mean by that

@epage
Copy link
Member Author

epage commented Oct 12, 2021

Currently, most cases that take a single value have signatures like

    pub fn alias<S: Into<&'help str>>(mut self, name: S) -> Self {
        self.aliases.push((name.into(), false));
        self
    }

Currently, that looks like

    pub fn alias<S: Into<&'help str>>(mut self, name: S) -> Self {
        self.aliases.push((name.into(), false));
        self
    }

This PR changes it to

    pub fn aliases<I, T>(mut self, names: I) -> Self
    where
        I: IntoIterator<Item = T>,
        T: Into<&'help str>,
    {
        self.aliases
            .extend(names.into_iter().map(|x| (x.into(), false)));
        self
    }

So value_names's T matches value_name's S.

@pksunkara
Copy link
Member

Ah, yeah we should not mind the signature being inconsistent between singular and plural apis as long as all kinds of inputs are accepted by the function.

@pksunkara
Copy link
Member

@epage
Copy link
Member Author

epage commented Oct 14, 2021

I played with it some more and, as expected, received some lifetime complaints (because I am not taking the approach of doing a &AsRef<str>.

We should defer this

  • As I said before, this can become trivial when we change our string type and we should just wait until then rather than forcing something to work that is a half measure to then just spend the time to fix it again later.
  • In general, I think this ends up being more of a distraction from the current release. We should be focusing more on the work already done rather than continuing new work.

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