cel-cxx 0.2.5

A high-performance, type-safe Rust interface for Common Expression Language (CEL), build on top of cel-cpp with zero-cost FFI bindings via cxx
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
# Math 扩展

Math 扩展为 CEL 标准库提供了基本算术运算之外的数学函数和操作。

## 目录

- [Math 扩展]#math-扩展
  - [目录]#目录
  - [1. 概述]#1-概述
  - [2. 最小值和最大值操作]#2-最小值和最大值操作
    - [2.1 math.greatest()]#21-mathgreatest
    - [2.2 math.least()]#22-mathleast
  - [3. 绝对值和符号]#3-绝对值和符号
    - [3.1 math.abs()]#31-mathabs
    - [3.2 math.sign()]#32-mathsign
  - [4. 舍入函数]#4-舍入函数
    - [4.1 math.ceil()]#41-mathceil
    - [4.2 math.floor()]#42-mathfloor
    - [4.3 math.round()]#43-mathround
    - [4.4 math.trunc()]#44-mathtrunc
  - [5. 位运算操作]#5-位运算操作
    - [5.1 math.bitAnd()]#51-mathbitand
    - [5.2 math.bitOr()]#52-mathbitor
    - [5.3 math.bitXor()]#53-mathbitxor
    - [5.4 math.bitNot()]#54-mathbitnot
    - [5.5 math.bitShiftLeft()]#55-mathbitshiftleft
    - [5.6 math.bitShiftRight()]#56-mathbitshiftright
  - [6. 浮点数辅助函数]#6-浮点数辅助函数
    - [6.1 math.isInf()]#61-mathisinf
    - [6.2 math.isNaN()]#62-mathisnan
    - [6.3 math.isFinite()]#63-mathisfinite
  - [7. 平方根]#7-平方根
    - [7.1 math.sqrt()]#71-mathsqrt
  - [8. 使用示例]#8-使用示例
    - [范围验证]#范围验证
    - [统计操作]#统计操作
    - [舍入和格式化]#舍入和格式化
    - [位标志]#位标志
    - [浮点数验证]#浮点数验证

## 1. 概述

Math 扩展通过表达式中常用的附加数学函数增强了 CEL。所有函数都是确定性的且无副作用。

**注意**:所有宏都使用 'math' 命名空间;但是,在宏展开时,命名空间看起来就像任何其他标识符一样。如果您当前使用名为 'math' 的变量,宏可能会按预期工作;但是,存在一些冲突的可能性。

**启用扩展**:
```rust
let env = Env::builder()
    .with_ext_math(true)
    .build()?;
```

## 2. 最小值和最大值操作

### 2.1 math.greatest()

返回宏参数中存在的最大值数字。

**语法:**
- `math.greatest(<arg>, ...)`

**参数:**
- 变参数量宏,必须至少接受一个参数
- 支持简单的数值和列表字面量作为有效参数类型
- 其他字面量在宏展开期间会被标记为错误

**返回类型:** 根据输入返回 `double`、`int` 或 `uint`

**示例:**
```cel
math.greatest(1)                             // 1
math.greatest(1u, 2u)                        // 2u
math.greatest(-42.0, -21.5, -100.0)         // -21.5
math.greatest([-42.0, -21.5, -100.0])       // -21.5
math.greatest(numbers)                       // numbers 必须是 list(numeric)
```

**错误情况:**
```cel
math.greatest()                              // 解析错误
math.greatest('string')                      // 解析错误
math.greatest(a, b)                          // 如果 a 或 b 不是数值类型,则为检查时错误
math.greatest(dyn('string'))                 // 运行时错误
```

### 2.2 math.least()

返回宏参数中存在的最小值数字。

**语法:**
- `math.least(<arg>, ...)`

**参数:**
- 变参数量宏,必须至少接受一个参数
- 支持简单的数值和列表字面量作为有效参数类型
- 其他字面量在宏展开期间会被标记为错误

**返回类型:** 根据输入返回 `double`、`int` 或 `uint`

**示例:**
```cel
math.least(1)                                // 1
math.least(1u, 2u)                           // 1u
math.least(-42.0, -21.5, -100.0)            // -100.0
math.least([-42.0, -21.5, -100.0])          // -100.0
math.least(numbers)                          // numbers 必须是 list(numeric)
```

**错误情况:**
```cel
math.least()                                 // 解析错误
math.least('string')                         // 解析错误
math.least(a, b)                             // 如果 a 或 b 不是数值类型,则为检查时错误
math.least(dyn('string'))                    // 运行时错误
```

## 3. 绝对值和符号

### 3.1 math.abs()

返回作为输入提供的数值类型的绝对值。如果值是 NaN,输出也是 NaN。如果输入是 int64 最小值,函数将导致溢出错误。

**语法:** `math.abs(number)`

**参数:**
- `number`:数值(int、uint 或 double)

**返回类型:** 与输入类型相同

**示例:**
```cel
math.abs(-1)                                 // 1
math.abs(1)                                  // 1
math.abs(-5.5)                               // 5.5
math.abs(0)                                  // 0
math.abs(42u)                                // 42u
```

**错误情况:**
```cel
math.abs(-9223372036854775808)               // 溢出错误(int64 最小值)
```

### 3.2 math.sign()

返回数值类型的符号,根据重载返回 -1、0 或 1 的 int、double 或 uint。对于浮点值,如果输入 NaN,输出也是 NaN。实现不区分正零和负零。

**语法:** `math.sign(number)`

**参数:**
- `number`:数值(int、uint 或 double)

**返回类型:** 与输入类型相同(-1、0 或 1)

**示例:**
```cel
math.sign(-42)                               // -1
math.sign(0)                                 // 0
math.sign(42)                                // 1
math.sign(-3.14)                             // -1.0
math.sign(0.0)                               // 0.0
math.sign(2.71)                              // 1.0
```

## 4. 舍入函数

### 4.1 math.ceil()

计算 double 值的上限。

**语法:** `math.ceil(number)`

**参数:**
- `number`:Double 值

**返回类型:** `double`

**示例:**
```cel
math.ceil(1.2)                               // 2.0
math.ceil(-1.2)                              // -1.0
math.ceil(5.0)                               // 5.0
math.ceil(0.1)                               // 1.0
```

### 4.2 math.floor()

计算 double 值的下限。

**语法:** `math.floor(number)`

**参数:**
- `number`:Double 值

**返回类型:** `double`

**示例:**
```cel
math.floor(1.2)                              // 1.0
math.floor(-1.2)                             // -2.0
math.floor(5.0)                              // 5.0
math.floor(0.9)                              // 0.0
```

### 4.3 math.round()

将 double 值舍入到最接近的整数,平局时远离零舍入,例如 1.5 -> 2.0,-1.5 -> -2.0。

**语法:** `math.round(number)`

**参数:**
- `number`:Double 值

**返回类型:** `double`

**示例:**
```cel
math.round(1.2)                              // 1.0
math.round(1.5)                              // 2.0
math.round(-1.5)                             // -2.0
math.round(3.14)                             // 3.0
math.round(3.64)                             // 4.0
```

### 4.4 math.trunc()

截断 double 值的小数部分。

**语法:** `math.trunc(number)`

**参数:**
- `number`:Double 值

**返回类型:** `double`

**示例:**
```cel
math.trunc(-1.3)                             // -1.0
math.trunc(1.3)                              // 1.0
math.trunc(3.14)                             // 3.0
math.trunc(-2.71)                            // -2.0
```

## 5. 位运算操作

### 5.1 math.bitAnd()

对两个 int 或 uint 值执行按位与操作。

**语法:**
- `math.bitAnd(<int>, <int>)` -> `<int>`
- `math.bitAnd(<uint>, <uint>)` -> `<uint>`

**参数:**
- 两个相同类型的整数(int 或 uint)

**返回类型:** 与输入类型相同

**示例:**
```cel
math.bitAnd(3u, 2u)                          // 2u
math.bitAnd(3, 5)                            // 1
math.bitAnd(-3, -5)                          // -7
math.bitAnd(12, 10)                          // 8 (1100 & 1010 = 1000)
```

### 5.2 math.bitOr()

对两个 int 或 uint 值执行按位或操作。

**语法:**
- `math.bitOr(<int>, <int>)` -> `<int>`
- `math.bitOr(<uint>, <uint>)` -> `<uint>`

**参数:**
- 两个相同类型的整数(int 或 uint)

**返回类型:** 与输入类型相同

**示例:**
```cel
math.bitOr(1u, 2u)                           // 3u
math.bitOr(-2, -4)                           // -2
math.bitOr(12, 10)                           // 14 (1100 | 1010 = 1110)
```

### 5.3 math.bitXor()

对两个 int 或 uint 值执行按位异或操作。

**语法:**
- `math.bitXor(<int>, <int>)` -> `<int>`
- `math.bitXor(<uint>, <uint>)` -> `<uint>`

**参数:**
- 两个相同类型的整数(int 或 uint)

**返回类型:** 与输入类型相同

**示例:**
```cel
math.bitXor(3u, 5u)                          // 6u
math.bitXor(1, 3)                            // 2
math.bitXor(12, 10)                          // 6 (1100 ^ 1010 = 0110)
```

### 5.4 math.bitNot()

接受单个 int 或 uint 并对给定二进制值执行按位非(一的补码)操作的函数。

**语法:**
- `math.bitNot(<int>)` -> `<int>`
- `math.bitNot(<uint>)` -> `<uint>`

**参数:**
- 单个整数(int 或 uint)

**返回类型:** 与输入类型相同

**示例:**
```cel
math.bitNot(1)                               // -2
math.bitNot(-1)                              // 0
math.bitNot(0u)                              // 18446744073709551615u
```

### 5.5 math.bitShiftLeft()

对第一个参数执行位左移操作,移位数量由第二个参数指定。第一个参数是 uint 或 int。第二个参数必须是 int。

当第二个参数为 64 或更大时,总是返回 0,因为移位的位数大于或等于被移位数字的总位长度。负值位移将导致运行时错误。

**语法:**
- `math.bitShiftLeft(<int>, <int>)` -> `<int>`
- `math.bitShiftLeft(<uint>, <int>)` -> `<uint>`

**参数:**
- 第一个参数:要移位的整数值(int 或 uint)
- 第二个参数:左移的位数(int)

**返回类型:** 与第一个参数类型相同

**示例:**
```cel
math.bitShiftLeft(1, 2)                      // 4
math.bitShiftLeft(-1, 2)                     // -4
math.bitShiftLeft(1u, 2)                     // 4u
math.bitShiftLeft(1u, 200)                   // 0u
math.bitShiftLeft(5, 2)                      // 20 (101 << 2 = 10100)
```

### 5.6 math.bitShiftRight()

对第一个参数执行位右移操作,移位数量由第二个参数指定。第一个参数是 uint 或 int。第二个参数必须是 int。

当第二个参数为 64 或更大时,总是返回 0,因为移位的位数大于或等于被移位数字的总位长度。负值位移将导致运行时错误。

此操作不会保留符号位扩展:左侧的空位用 0 填充。

**语法:**
- `math.bitShiftRight(<int>, <int>)` -> `<int>`
- `math.bitShiftRight(<uint>, <int>)` -> `<uint>`

**参数:**
- 第一个参数:要移位的整数值(int 或 uint)
- 第二个参数:右移的位数(int)

**返回类型:** 与第一个参数类型相同

**示例:**
```cel
math.bitShiftRight(1024, 2)                  // 256
math.bitShiftRight(1024u, 2)                 // 256u
math.bitShiftRight(1024u, 64)                // 0u
math.bitShiftRight(20, 2)                    // 5 (10100 >> 2 = 101)
```

## 6. 浮点数辅助函数

### 6.1 math.isInf()

如果输入的 double 值是 -Inf 或 +Inf,返回 true。

**语法:** `math.isInf(<double>)` -> `<bool>`

**参数:**
- `number`:Double 值

**返回类型:** `bool`

**示例:**
```cel
math.isInf(1.0/0.0)                          // true
math.isInf(-1.0/0.0)                         // true
math.isInf(1.2)                              // false
math.isInf(0.0)                              // false
```

### 6.2 math.isNaN()

如果输入的 double 值是 NaN,返回 true,否则返回 false。

**语法:** `math.isNaN(<double>)` -> `<bool>`

**参数:**
- `number`:Double 值

**返回类型:** `bool`

**示例:**
```cel
math.isNaN(0.0/0.0)                          // true
math.isNaN(1.2)                              // false
math.isNaN(1.0/0.0)                          // false(这是 Inf,不是 NaN)
```

### 6.3 math.isFinite()

如果值是有限数字,返回 true。行为等同于:`!math.isNaN(double) && !math.isInf(double)`

**语法:** `math.isFinite(<double>)` -> `<bool>`

**参数:**
- `number`:Double 值

**返回类型:** `bool`

**示例:**
```cel
math.isFinite(0.0/0.0)                       // false(NaN)
math.isFinite(1.0/0.0)                       // false(Inf)
math.isFinite(1.2)                           // true
math.isFinite(-42.5)                         // true
```

## 7. 平方根

### 7.1 math.sqrt()

返回给定输入的平方根作为 double。对于负数或非数值输入抛出错误。

**语法:**
- `math.sqrt(<double>)` -> `<double>`
- `math.sqrt(<int>)` -> `<double>`
- `math.sqrt(<uint>)` -> `<double>`

**参数:**
- `number`:数值(int、uint 或 double)

**返回类型:** `double`

**示例:**
```cel
math.sqrt(81)                                // 9.0
math.sqrt(985.25)                            // 31.388692231439016
math.sqrt(0)                                 // 0.0
math.sqrt(4u)                                // 2.0
```

**错误情况:**
```cel
math.sqrt(-15)                               // 返回 NaN
```

## 8. 使用示例

### 范围验证
```cel
// 使用 greatest/least 检查值是否在可接受范围内
cel.bind(value, 75,
  cel.bind(bounds, [0, 100],
    value >= math.least(bounds) && value <= math.greatest(bounds) &&
    math.abs(value - 50) <= 25
  )
)
// 结果:true
```

### 统计操作
```cel
// 计算基本统计信息
cel.bind(numbers, [1, 2, 3, 4, 5],
  {
    "min": math.least(numbers),
    "max": math.greatest(numbers),
    "range": math.greatest(numbers) - math.least(numbers),
    "mean_approx": math.trunc((math.greatest(numbers) + math.least(numbers)) / 2.0),
    "abs_values": numbers.map(n, math.abs(n))
  }
)
```

### 舍入和格式化
```cel
// 舍入货币值
cel.bind(price, 19.99,
  {
    "floor": math.floor(price),
    "ceil": math.ceil(price),
    "round": math.round(price),
    "trunc": math.trunc(price),
    "sqrt_price": math.sqrt(price)
  }
)
// 结果:{"floor": 19.0, "ceil": 20.0, "round": 20.0, "trunc": 19.0, "sqrt_price": 4.47...}
```

### 位标志
```cel
// 检查权限标志
cel.bind(permissions, 7,  // 二进制:111
  cel.bind(read_flag, 1,  // 二进制:001
    cel.bind(write_flag, 2, // 二进制:010
      cel.bind(exec_flag, 4, // 二进制:100
        {
          "can_read": math.bitAnd(permissions, read_flag) != 0,
          "can_write": math.bitAnd(permissions, write_flag) != 0,
          "can_execute": math.bitAnd(permissions, exec_flag) != 0,
          "full_access": permissions == math.bitOr(math.bitOr(read_flag, write_flag), exec_flag),
          "shifted_perms": math.bitShiftLeft(permissions, 1)
        }
      )
    )
  )
)
```

### 浮点数验证
```cel
// 验证浮点数
cel.bind(values, [1.5, 1.0/0.0, 0.0/0.0, -42.7],
  values.map(v, {
    "value": v,
    "is_finite": math.isFinite(v),
    "is_inf": math.isInf(v),
    "is_nan": math.isNaN(v),
    "sign": math.isFinite(v) ? math.sign(v) : 0.0,
    "sqrt": v >= 0 && math.isFinite(v) ? math.sqrt(v) : 0.0
  })
)
```

Math 扩展提供了补充 CEL 基本算术的基本数学操作,使表达式能够进行更复杂的数值计算。