1212# See the License for the specific language governing permissions and
1313# limitations under the License.
1414
15+ import math
1516from ipaddress import IPv4Address , IPv6Address , ip_address
1617from urllib import parse as urlparse
1718
@@ -105,6 +106,31 @@ def is_hostname(string: celtypes.Value) -> celpy.Result:
105106 return celtypes .BoolType (_validate_hostname (string ))
106107
107108
109+ def is_nan (val : celtypes .Value ) -> celpy .Result :
110+ if not isinstance (val , celtypes .DoubleType ):
111+ msg = "invalid argument, expected double"
112+ raise celpy .EvalError (msg )
113+ return celtypes .BoolType (math .isnan (val ))
114+
115+
116+ def is_inf (val : celtypes .Value , sign : None | celtypes .Value = None ) -> celpy .Result :
117+ if not isinstance (val , celtypes .DoubleType ):
118+ msg = "invalid argument, expected double"
119+ raise celpy .EvalError (msg )
120+ if sign is None :
121+ return celtypes .BoolType (math .isinf (val ))
122+
123+ if not isinstance (sign , celtypes .IntType ):
124+ msg = "invalid argument, expected int"
125+ raise celpy .EvalError (msg )
126+ if sign > 0 :
127+ return celtypes .BoolType (math .isinf (val ) and val > 0 )
128+ elif sign < 0 :
129+ return celtypes .BoolType (math .isinf (val ) and val < 0 )
130+ else :
131+ return celtypes .BoolType (math .isinf (val ))
132+
133+
108134def unique (val : celtypes .Value ) -> celpy .Result :
109135 if not isinstance (val , celtypes .ListType ):
110136 msg = "invalid argument, expected list"
@@ -115,7 +141,11 @@ def unique(val: celtypes.Value) -> celpy.Result:
115141def make_extra_funcs (locale : str ) -> dict [str , celpy .CELFunction ]:
116142 string_fmt = string_format .StringFormat (locale )
117143 return {
144+ # Missing standard functions
118145 "format" : string_fmt .format ,
146+ # protovalidate specific functions
147+ "isNan" : is_nan ,
148+ "isInf" : is_inf ,
119149 "isIp" : is_ip ,
120150 "isEmail" : is_email ,
121151 "isUri" : is_uri ,
0 commit comments