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

Allow custom arbitrary methods for fields in the custom derive #33

Closed
fitzgen opened this issue Feb 21, 2020 · 10 comments
Closed

Allow custom arbitrary methods for fields in the custom derive #33

fitzgen opened this issue Feb 21, 2020 · 10 comments

Comments

@fitzgen
Copy link
Member

fitzgen commented Feb 21, 2020

Sometimes a field of a struct doesn't implement arbitrary and it is either impossible to do (because it is from another crate, for example) or undesired.

We should support some kind of attribute to either use the Default::default implementation for the type, when we "don't care" about that field, or supply an arbitrary function that has the same signature as Arbitrary::arbitrary to be used instead.

This is all possible to do when implementing Arbitrary by hand, in the sense that you can always stuff whatever code inside the impl. But this seems common enough and simple enough that we may want to support it in the custom derive.

Straw person syntax:

#[derive(Arbitrary)]
struct MyThing {
    // This doesn't actually matter, just a diagnostic message, so don't
    // waste input bytes on it.
    #[arbitrary(default)]
    diagnostic: String,

    // This is a type defined by a foreign crate and doesn't implement
    // Arbitrary. Because of orphan rules, we can't implement Arbitrary
    // for it, so instead we have a one-off function.
    #[arbitrary(arbitrary = arbitrary_foreign_type)]
    foreign: foreign_crate::ForeignType,
}

fn arbitrary_foreign_type(u: &mut Unstructured)
    -> Result<foreign_crate::ForeignType>
{
    // ...
}

The open question in my mind is how to deal with the other, optional Arbtirary methods? e.g. arbitrary_take_rest, shrink, and size_hint. Should we assume the default implementations in this case? Should we also allow providing custom implementations for them?

Any thoughts @Manishearth?

+cc @bnjbvr

@Manishearth
Copy link
Member

No strong thoughts, we can allow multiple methods for overriding it perhaps.

@h4l7
Copy link

h4l7 commented Mar 30, 2022

Is this still in the pipeline? Would significantly simplify my use case testing reasonably complex serde structures.

@fitzgen
Copy link
Member Author

fitzgen commented Mar 30, 2022

AFAIK, no one has ever started implementing this. It seems like it is generally wanted/useful, so if you want to take a shot at implementing it, I would be happy to review/give feedback/etc.

@evanrichter
Copy link

in cases where it's only the orphan rules prevent deriving Arbitrary, we could do a remote derive like serde does. I also like the idea of a function override as described before, and there's not full overlap

@greyblake
Copy link
Contributor

I would love to have this. Otherwise it's almost impossible to apply Arbitrary in a big project, because there is always 2-3% of fields, that are not like others.

@greyblake
Copy link
Contributor

FYI: I created ArbitraryExt crate which provides a temporal workaround for this problem.

@fitzgen
Copy link
Member Author

fitzgen commented Oct 18, 2022

Would you like to turn that into a pull request for this crate?

@greyblake
Copy link
Contributor

@fitzgen Sure.

For now, ArbitraryExt is a quick and dirty prototype. E.g. I just applied it to my code base, it I quickly found that a few things are missing. Once I implement everything I need and test it against a large code base, I will port it to Arbitrary and open a PR. I'll keep you updated.

@greyblake
Copy link
Contributor

@fitzgen Ok, I've opened a PR: #129

@greyblake
Copy link
Contributor

This can be marked as resolved (since #129 is merged)

@fitzgen fitzgen closed this as completed Oct 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants