|
15 | 15 | import celpy # type: ignore
|
16 | 16 | from celpy import celtypes # type: ignore
|
17 | 17 |
|
18 |
| -QUOTE_TRANS = str.maketrans( |
19 |
| - { |
20 |
| - "\a": r"\a", |
21 |
| - "\b": r"\b", |
22 |
| - "\f": r"\f", |
23 |
| - "\n": r"\n", |
24 |
| - "\r": r"\r", |
25 |
| - "\t": r"\t", |
26 |
| - "\v": r"\v", |
27 |
| - "\\": r"\\", |
28 |
| - '"': r"\"", |
29 |
| - } |
30 |
| -) |
31 |
| - |
32 |
| - |
33 |
| -def quote(s: str) -> str: |
34 |
| - return '"' + s.translate(QUOTE_TRANS) + '"' |
35 |
| - |
36 | 18 |
|
37 | 19 | class StringFormat:
|
38 | 20 | """An implementation of string.format() in CEL."""
|
39 | 21 |
|
40 | 22 | def __init__(self, locale: str):
|
41 | 23 | self.locale = locale
|
42 | 24 |
|
43 |
| - def format(self, fmt: celtypes.Value, args: celtypes.Value) -> celpy.Result: |
| 25 | + def format(self, fmt: celtypes.Value, _: celtypes.Value) -> celpy.Result: |
44 | 26 | if not isinstance(fmt, celtypes.StringType):
|
45 | 27 | return celpy.CELEvalError("format() requires a string as the first argument")
|
46 |
| - if not isinstance(args, celtypes.ListType): |
47 |
| - return celpy.CELEvalError("format() requires a list as the second argument") |
48 |
| - # printf style formatting |
49 |
| - i = 0 |
50 |
| - j = 0 |
51 |
| - result = "" |
52 |
| - while i < len(fmt): |
53 |
| - if fmt[i] != "%": |
54 |
| - result += fmt[i] |
55 |
| - i += 1 |
56 |
| - continue |
57 |
| - |
58 |
| - if i + 1 < len(fmt) and fmt[i + 1] == "%": |
59 |
| - result += "%" |
60 |
| - i += 2 |
61 |
| - continue |
62 |
| - if j >= len(args): |
63 |
| - return celpy.CELEvalError("format() not enough arguments for format string") |
64 |
| - arg = args[j] |
65 |
| - j += 1 |
66 |
| - i += 1 |
67 |
| - if i >= len(fmt): |
68 |
| - return celpy.CELEvalError("format() incomplete format specifier") |
69 |
| - precision = 6 |
70 |
| - if fmt[i] == ".": |
71 |
| - i += 1 |
72 |
| - precision = 0 |
73 |
| - while i < len(fmt) and fmt[i].isdigit(): |
74 |
| - precision = precision * 10 + int(fmt[i]) |
75 |
| - i += 1 |
76 |
| - if i >= len(fmt): |
77 |
| - return celpy.CELEvalError("format() incomplete format specifier") |
78 |
| - if fmt[i] == "f": |
79 |
| - result += self.format_float(arg, precision) |
80 |
| - if fmt[i] == "e": |
81 |
| - result += self.format_exponential(arg, precision) |
82 |
| - elif fmt[i] == "d": |
83 |
| - result += self.format_int(arg) |
84 |
| - elif fmt[i] == "s": |
85 |
| - result += self.format_string(arg) |
86 |
| - elif fmt[i] == "x": |
87 |
| - result += self.format_hex(arg) |
88 |
| - elif fmt[i] == "X": |
89 |
| - result += self.format_hex(arg).upper() |
90 |
| - elif fmt[i] == "o": |
91 |
| - result += self.format_oct(arg) |
92 |
| - elif fmt[i] == "b": |
93 |
| - result += self.format_bin(arg) |
94 |
| - else: |
95 |
| - return celpy.CELEvalError("format() unknown format specifier: " + fmt[i]) |
96 |
| - i += 1 |
97 |
| - if j < len(args): |
98 |
| - return celpy.CELEvalError("format() too many arguments for format string") |
99 |
| - return celtypes.StringType(result) |
100 |
| - |
101 |
| - def format_float(self, arg: celtypes.Value, precision: int) -> celpy.Result: |
102 |
| - if isinstance(arg, celtypes.DoubleType): |
103 |
| - return celtypes.StringType(f"{arg:.{precision}f}") |
104 |
| - return self.format_int(arg) |
105 |
| - |
106 |
| - def format_exponential(self, arg: celtypes.Value, precision: int) -> celpy.Result: |
107 |
| - if isinstance(arg, celtypes.DoubleType): |
108 |
| - return celtypes.StringType(f"{arg:.{precision}e}") |
109 |
| - return self.format_int(arg) |
110 |
| - |
111 |
| - def format_int(self, arg: celtypes.Value) -> celpy.Result: |
112 |
| - if isinstance(arg, celtypes.IntType): |
113 |
| - return celtypes.StringType(arg) |
114 |
| - if isinstance(arg, celtypes.UintType): |
115 |
| - return celtypes.StringType(arg) |
116 |
| - return celpy.CELEvalError("format_int() requires an integer argument") |
117 |
| - |
118 |
| - def format_hex(self, arg: celtypes.Value) -> celpy.Result: |
119 |
| - if isinstance(arg, celtypes.IntType): |
120 |
| - return celtypes.StringType(f"{arg:x}") |
121 |
| - if isinstance(arg, celtypes.UintType): |
122 |
| - return celtypes.StringType(f"{arg:x}") |
123 |
| - if isinstance(arg, celtypes.BytesType): |
124 |
| - return celtypes.StringType(arg.hex()) |
125 |
| - if isinstance(arg, celtypes.StringType): |
126 |
| - return celtypes.StringType(arg.encode("utf-8").hex()) |
127 |
| - return celpy.CELEvalError("format_hex() requires an integer, string, or binary argument") |
128 |
| - |
129 |
| - def format_oct(self, arg: celtypes.Value) -> celpy.Result: |
130 |
| - if isinstance(arg, celtypes.IntType): |
131 |
| - return celtypes.StringType(f"{arg:o}") |
132 |
| - if isinstance(arg, celtypes.UintType): |
133 |
| - return celtypes.StringType(f"{arg:o}") |
134 |
| - return celpy.CELEvalError("format_oct() requires an integer argument") |
135 |
| - |
136 |
| - def format_bin(self, arg: celtypes.Value) -> celpy.Result: |
137 |
| - if isinstance(arg, celtypes.IntType): |
138 |
| - return celtypes.StringType(f"{arg:b}") |
139 |
| - if isinstance(arg, celtypes.UintType): |
140 |
| - return celtypes.StringType(f"{arg:b}") |
141 |
| - if isinstance(arg, celtypes.BoolType): |
142 |
| - return celtypes.StringType(f"{arg:b}") |
143 |
| - return celpy.CELEvalError("format_bin() requires an integer argument") |
144 |
| - |
145 |
| - def format_string(self, arg: celtypes.Value) -> celpy.Result: |
146 |
| - if isinstance(arg, celtypes.StringType): |
147 |
| - return arg |
148 |
| - if isinstance(arg, celtypes.BytesType): |
149 |
| - return celtypes.StringType(arg.hex()) |
150 |
| - if isinstance(arg, celtypes.ListType): |
151 |
| - return self.format_list(arg) |
152 |
| - return celtypes.StringType(arg) |
153 |
| - |
154 |
| - def format_value(self, arg: celtypes.Value) -> celpy.Result: |
155 |
| - if isinstance(arg, (celtypes.StringType, str)): |
156 |
| - return celtypes.StringType(quote(arg)) |
157 |
| - if isinstance(arg, celtypes.UintType): |
158 |
| - return celtypes.StringType(arg) |
159 |
| - return self.format_string(arg) |
160 |
| - |
161 |
| - def format_list(self, arg: celtypes.ListType) -> celpy.Result: |
162 |
| - result = "[" |
163 |
| - for i in range(len(arg)): |
164 |
| - if i > 0: |
165 |
| - result += ", " |
166 |
| - result += self.format_value(arg[i]) |
167 |
| - result += "]" |
168 |
| - return celtypes.StringType(result) |
| 28 | + return celtypes.StringType(fmt) |
169 | 29 |
|
170 | 30 |
|
171 | 31 | _default_format = StringFormat("en_US")
|
172 | 32 | format = _default_format.format # noqa: A001
|
173 |
| -format_value = _default_format.format_value |
0 commit comments