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

Add collection .IfAny() .IfSingle() .IfNotSingle() .IfNone() .IfAll() #20

Open
amantinband opened this issue Mar 10, 2022 · 14 comments
Open
Labels
enhancement New feature or request

Comments

@amantinband
Copy link
Owner

Add the following collection validations:

var collection = new[] { 1, 2, 3, 3 };

collection.Throw().IfAny(item => item == 3);
collection.Throw().IfSingle(item => item == 2);
collection.Throw().IfNotSingle(item => item == 3);
collection.Throw().IfNone(item => item == 0);
collection.Throw().IfAll(item => item > 0);
@amantinband amantinband added enhancement New feature or request good first issue Good for newcomers labels Mar 10, 2022
@dwakel
Copy link
Contributor

dwakel commented Mar 11, 2022

@mantinband
Just to clarify if single is when only one element in the collection is equal to 2
And not single is when more than one element is equal to 3

@dwakel
Copy link
Contributor

dwakel commented Mar 11, 2022

I picked up this issue. Currently writing test.
This is probably my first open-source contribution ever
I've enjoyed working on this

@amantinband
Copy link
Owner Author

Awesome, that was quick! Let me know If you have any questions. Also, feel free to split this into multiple PRs if that would be more convenient 🙂

@dwakel
Copy link
Contributor

dwakel commented Mar 11, 2022

@mantinband
should these extensions be able to evaluate any type.

Im assuming for
collection.Throw().IfAny(item => item == 3);
It should accept an expression which can evaluate
item => item > 3
item => item < 3
item => item <= 3
(Any inequality expression)

This however wont yield same results for a collection of strings unless a numeric property or function of the string (Count, Length, etc.) is Invoked

@amantinband
Copy link
Owner Author

I was thinking of something similar to this draft PR: #25
WDYT?

There is a C# language limitation that we cannot specify the method declaration as following:

    public static ref readonly Validatable<TValue> IfAny<TValue, TItem>(this in Validatable<TValue<TItem>> validatable, Func<TItem, bool> predicate, [CallerArgumentExpression("predicate")] string? predicateName = null)

Unfortunately in this implementation, we need to disambiguate the predicate's input parameter (int x in the draft PR). Couldn't find a way around this..

@amantinband
Copy link
Owner Author

@dwakel
Take a look at the latest iteration of #25. This works as you would expect. The only downfall is that it boxes the Validatable struct which will hurt performance. I wonder if there is a way around this

@dwakel
Copy link
Contributor

dwakel commented Mar 13, 2022

@mantinband
I noticed the validatable doesn't return TCollectionType but just encapsulates an IEnumerable directly.
It also didn't occur to me that you could just pass the inequality condition as a Func<item,bool> 😄
The picture I had in my mind was to accept an Expression type then evaluate it using LINQ

@amantinband amantinband removed the good first issue Good for newcomers label Mar 13, 2022
@dwakel
Copy link
Contributor

dwakel commented Mar 20, 2022

Should these operations be limited to a subset ⊆ of Rational numbers

@amantinband
Copy link
Owner Author

Nah, I think the main use case will be on complex objects and not on collections of rational numbers/strings

@dwakel
Copy link
Contributor

dwakel commented Mar 23, 2022

I'm going to jump back to working on this issue

@SakuraIsayeki
Copy link

Hi there! Just jumping into the pool. Is the issue still being worked on? Or is it up for grabs?
I'm eager to contribute to this lib, so if there's anything I can add... Might as well start here ^^

@dwakel
Copy link
Contributor

dwakel commented Sep 6, 2022

Hey @SakuraIsayeki you could definitely look at this issue.
Please also share any insights you have. It'll be nice knowing how you would go about implementing this

@SakuraIsayeki
Copy link

SakuraIsayeki commented Sep 6, 2022

Okay. I see where the snag lies.

To recap, the current issue has us unable to determine IfAny()'s TElement on this example :

Action action = () => collection.Throw().IfAny(x => x == "ho");
Action action2 = () => collection2.Throw().IfAny(x => x == 1);

Where IfAny() is plagued with the same issue, namely The type arguments for method 'ref readonly Validatable<TValue> Throw.ValidatableExtensions.IfAny<TValue,TElement>(this in Validatable<TValue>, Expression<Func<TElement,bool>>)' cannot be inferred from the usage..

Here's what I have so far: SakuraIsayeki@7e87a42

This got me thinking...

How did they manage it on FluentAssertions?

FluentAssertions would have it as so:

collection.Should().Satisfy(x => x == "ho");
collection2.Should().Satisfy(x => x == 1);

And it just works. Here's the catch tho ; These buggers used IEnumerable<T> as the arg type on Should()! And honestly this is briliant. They're essentially only exposing one generic, and that's the Item type.


I suspect what's left to do is to somehow hack Throw() around accepting IEnumerable<T> as its entry parameter. Could you please @amantinband advise us on how feasible this would be, in regards to the library itself, and how you've planned its development this far?

SakuraIsayeki added a commit to SakuraIsayeki/throw that referenced this issue Sep 7, 2022
Draft for Issue amantinband#20.
The extension method is DOA, due to generics not resolving properly. 
See: amantinband#20 (comment)
@Mitchman215
Copy link

Any update on this? It would be really useful to have this feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants