|
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.""" |
@@ -61,113 +43,12 @@ def format(self, fmt: celtypes.Value, args: celtypes.Value) -> celpy.Result: |
61 | 43 | continue |
62 | 44 | if j >= len(args): |
63 | 45 | return celpy.CELEvalError("format() not enough arguments for format string") |
64 | | - arg = args[j] |
65 | 46 | j += 1 |
66 | 47 | 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 | 48 | if j < len(args): |
98 | 49 | return celpy.CELEvalError("format() too many arguments for format string") |
99 | 50 | return celtypes.StringType(result) |
100 | 51 |
|
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) |
169 | | - |
170 | 52 |
|
171 | 53 | _default_format = StringFormat("en_US") |
172 | 54 | format = _default_format.format # noqa: A001 |
173 | | -format_value = _default_format.format_value |
0 commit comments