I would like to be able to check the given data, when a freezed object is constructed, somewhat like assert statements in normal constructors.
I propose the following syntax:
@freezed
abstract class Foo with _$Foo {
@Assert((foo) => foo.value <= maxValue)
factory Foo({
@required double value,
@Default(double.infinity) double maxValue
}) = _Foo;
}
Would something like this be possible?
Alternatively a simpler approach would be an onConstruct callback like this:
@freezed
abstract class Foo with _$Foo {
factory Foo({
@required double value,
@Default(double.infinity) double maxValue
}) = _Foo;
@override
void onConstruct() {
assert(value <= maxValue);
}
}
What do you think of this?
@Assert((foo) => foo.value <= maxValue)
This is not a valid Dart syntax
void onConstruct() {
We would lose const constructors
What about:
@freezed
abstract class Foo with _$Foo {
@Assert('value <= maxValue')
factory Foo({
@required double value,
@Default(double.infinity) double maxValue
}) = _Foo;
}
?
We lose auto-completion but it's still type-safe, and this allows const constructors.
That would be a simple solution, but not very flexible. You would have to implement some special syntax checking, especially if one wants to check multiple properties (correct me, if I'm wrong).
I would rather accept the fact of loosing const factory constructors. Would it be possible to use the onConstructed callback only if the class factory isn't specified as const?
If that's not possible or wanted, I would also be fine with your proposal.
You would have to implement some special syntax checking, especially if one wants to check multiple properties
You could do:
@freezed
abstract class Foo with _$Foo {
@Assert('a > 0')
@Assert('b > 0')
@Assert('a > b')
factory Foo(int a, int b) = _Foo;
}
There's no need for special checking of any sort, since the string is used for generation.\
It's not evaluated or anything, where I would have to parse Dart syntax.
It would just transform @Assert('whatever') into assert(whatever)
Oh okay that sounds cool, I didn't know you could do this. I would appreciate this feature in a coming version.
Thank you!
There's no need for special checking of any sort, since the string is used for generation.
It's not evaluated or anything, where I would have to parse Dart syntax.It would just transform
@Assert('whatever')intoassert(whatever)
Does this mean, that syntax and other errors will be thrown at compile time (or in this case while the code is generated)?
Does this mean, that syntax and other errors will be thrown at compile time (or in this case while the code is generated)?
You will have a compilation error.
Would it be a more general apportion an option? If it would be possible to write your own factory method.
@freezed
abstract class Foo with _$Foo {
factory Foo({
@required double value,
@Default(double.infinity) double maxValue
}) {
if(value >= maxValue) {
throw MyCustomException
}
return _Foo(value, maxValue);
}
}
The benefits on this approach are
What you do think? Would that be possible?
@swissonid This is not feasible
It would exponentially increase the difficulty of parsing the name of the generated class (here _Foo).
@rrousselGit I also want this functionality. Assume following class:
@freezed
abstract class MyClass<T> implements _$MyClass<T> {
const MyClass._();
factory MyRepo(T a) = _MyClass<T>;
}
Here, I want to check whether the class was instantiated WITH generic type argument given.
That means,
MyClass<int> m = MyClass(5);
should be allowed.
But,
MyClass m = MyClass(5);
shouldn't be.
For this, I want to put an assert statement like this is resultant class:
assert(T != dynamic);
Most helpful comment
You will have a compilation error.