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 support for Constraint on the floating point count #5081

Closed
DimuthuMadushan opened this issue Oct 25, 2023 · 6 comments · Fixed by ballerina-platform/module-ballerina-constraint#102
Assignees
Labels
module/constraint Team/PCM Protocol connector packages related issues Type/NewFeature

Comments

@DimuthuMadushan
Copy link

Description:

$subject

Add support for Constraint on the floating point count in Constraint module. This may help to limit the number of a digits in a floating point number.

@TharmiganK TharmiganK self-assigned this Oct 25, 2023
@TharmiganK TharmiganK added the Team/PCM Protocol connector packages related issues label Oct 25, 2023
@TharmiganK TharmiganK moved this to In Progress in Ballerina Team Main Board Oct 25, 2023
@TharmiganK
Copy link
Contributor

The requested feature is similar to,

The proposed constraints

Constraint name Applies to constraint type Constraint value type Semantics (v is value being constrained, c is constraint value)
maxDigits @constraint:Int positive integer number of digits in v <= c
maxIntegerDigits @constraint:Float, @constraint:Number positive integer number of digits in the integer part of v <= c
maxFractionDigits @constraint:Float, @constraint:Number positive integer number of digits in the fraction part of v <= c

Usage

@constraint:Int {maxDigits: 4}
type Integer int;

@constraint:Float {maxIntegerDigits: 3, maxFractionDigits: 2}
type Float float;

@constraint:Number {maxFractionDigits: 3}
type Number int|decimal|float;

Additional validations

  • The value of the above constraint should be a positive integer. This validation will be done by the compiler plugin, if the value is provided inline. Otherwise, an error will be returned at runtime when we call validate.

@shafreenAnfar Can you review?

@TharmiganK
Copy link
Contributor

This constraint is also allowed on the built-in sub types of int such as int:Unsigned8, int:Unsigned16, int:Unsigned32, int:Signed8, int:Signed16 and int:Signed32. All these types has a digit limit according to their representation. The validation between that limit and the value provided by the constraint, is not performed at compiler time. But at runtime it will fail when we do value to type conversion(by cloneWithType which is called internally when we call validate method).
This behaviour is same as what we do for maxValue and minValue.

import ballerina/constraint;
import ballerina/log;

@constraint:Int {maxDigits: 4} // No compiler error
type Integer int:Signed8;

public function main() {
    // int:Signed8 a = 1000; // Compiler error from Lang

    Integer|error b = constraint:validate(1000); // No compiler error
    if b is error {
        // Type conversion failed due to typedesc and value mismatch.
        log:printError("error occurred", b);
    }
}

@lnash94
Copy link
Member

lnash94 commented Oct 27, 2023

This constraint is also allowed on the built-in sub types of int such as int:Unsigned8, int:Unsigned16, int:Unsigned32, int:Signed8, int:Signed16 and int:Signed32. All these types has a digit limit according to their representation. The validation between that limit and the value provided by the constraint, is not performed at compiler time. But at runtime it will fail when we do value to type conversion(by cloneWithType which is called internally when we call validate method). This behaviour is same as what we do for maxValue and minValue.

import ballerina/constraint;
import ballerina/log;

@constraint:Int {maxDigits: 4} // No compiler error
type Integer int:Signed8;

public function main() {
    // int:Signed8 a = 1000; // Compiler error from Lang

    Integer|error b = constraint:validate(1000); // No compiler error
    if b is error {
        // Type conversion failed due to typedesc and value mismatch.
        log:printError("error occurred", b);
    }
}

Does it validate the given value type during the runtime (ex: check whether it is signed32 or signed64) or its constraint validations (ex: check it exceeds or has constraint rules max digits )?

@TharmiganK
Copy link
Contributor

TharmiganK commented Oct 27, 2023

Does it validate the given value type during the runtime (ex: check whether it is signed32 or signed64)?

Yes, when we call the validate method at runtime, the first step is to clone the value with the type provided by the typedesc. Then only we execute the constraint validations.

For example, Integer|error b = constraint:validate(1000); here the typedesc is Integer which is a subtype of int:Signed8. So we first try to clone the value 1000 to this type. Then it will fail since the int:Signed8 cannot have a value greater than 127. Hence we return this error: Type conversion failed due to typedesc and value mismatch.

its constraint validations (ex: check it exceeds or has constraint rules max digits )?

There are no runtime rules on the maxDigits constraint value(other than it should be positive integer) depends on the type. It will still get executed.

@constraint:Int {maxDigits: 4} // No compiler error
type Integer int:Signed8;

public function main() {
    Integer|error b = constraint:validate(100); 
    // No runtime error for maxDigits constraint value
}

@lnash94
Copy link
Member

lnash94 commented Oct 27, 2023

Thank you @TharmiganK for the clarification. I'm wondering about the behaviour regarding the minDigits scenario[1]
[1] miniDigits scenario

@constraint:Int {minDigits: 4} 
type Integer int:Signed8;

public function main() {
    Integer|error b = constraint:validate(100); 
}

may this behave like the minimum in an integer value with int:Signed8?

@TharmiganK
Copy link
Contributor

I'm wondering about the behaviour regarding the minDigits scenario
may this behave like the minimum in an integer value with int:Signed8?

This proposal only covers the maxDigits constraint. I have not seen minDigits constraint in Java or XML schema. I think there are no actual use cases for that constraint. If it is requested we could support that.

But I could understand the concern when there is a minValue constraint on integer subtypes:

// The constraint value is not correct since `int:Signed8` cannot have values greater than 128
// Still we do not report a compiler error. This could be a compiler plugin validation
@constraint:Int {minValue: 128}
type Integer int:Signed8;

public function main() {
    Integer|error b = constraint:validate(102);
    // This will give an error saying validation failed for `minValue`
    // But actually we should give an error saying the value for `minValue` 
    // is not compatible with the type
}

We can create another issue to address this as an improvement

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
module/constraint Team/PCM Protocol connector packages related issues Type/NewFeature
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

3 participants