MCPcopy Create free account
hub / github.com/apache/datafusion / parse

Method parse

datafusion/spark/src/function/string/format_string.rs:285–359  ·  view source on GitHub ↗

Parses a printf-style format string into a Formatter with validation. This method implements a comprehensive parser for Java `java.util.Formatter` syntax, processing the format string character by character to identify and validate format specifiers against the provided argument types. # Arguments `fmt` - The format string containing literal text and format specifiers `arg_types` - Array of Dat

(fmt: &'a str, arg_types: &[DataType])

Source from the content-addressed store, hash-verified

283 /// Returns a Formatter containing the parsed elements and the maximum argument
284 /// index encountered, enabling efficient argument validation during formatting.
285 pub fn parse(fmt: &'a str, arg_types: &[DataType]) -> Result<Self> {
286 // find the first %
287 let mut res = Vec::new();
288
289 let mut rem = fmt;
290 let mut argument_index = 0;
291
292 let mut prev: Option<usize> = None;
293
294 while !rem.is_empty() {
295 if let Some((verbatim_prefix, rest)) = rem.split_once('%') {
296 if !verbatim_prefix.is_empty() {
297 res.push(FormatElement::Verbatim(verbatim_prefix));
298 }
299 if let Some(rest) = rest.strip_prefix('%') {
300 res.push(FormatElement::Verbatim("%"));
301 rem = rest;
302 continue;
303 }
304 if let Some(rest) = rest.strip_prefix('n') {
305 res.push(FormatElement::Verbatim("\n"));
306 rem = rest;
307 continue;
308 }
309 if let Some(rest) = rest.strip_prefix('<') {
310 // %< means reuse the previous argument
311 let Some(p) = prev else {
312 return exec_err!("No previous argument to reference");
313 };
314 let (spec, rest) =
315 take_conversion_specifier(rest, p, &arg_types[p - 1])?;
316 res.push(FormatElement::Format(spec));
317 rem = rest;
318 continue;
319 }
320
321 let (current_argument_index, rest2) = take_numeric_param(rest, false);
322 let (current_argument_index, rest) =
323 match (current_argument_index, rest2.starts_with('$')) {
324 (NumericParam::Literal(index), true) => {
325 (index as usize, &rest2[1..])
326 }
327 (NumericParam::FromArgument, true) => {
328 return exec_err!("Invalid numeric parameter");
329 }
330 (_, false) => {
331 argument_index += 1;
332 (argument_index, rest)
333 }
334 };
335 if current_argument_index == 0 || current_argument_index > arg_types.len()
336 {
337 return exec_err!(
338 "Argument index {} is out of bounds",
339 current_argument_index
340 );
341 }
342

Callers 3

handle_timestampMethod · 0.45
process_arraysFunction · 0.45
process_arraysFunction · 0.45

Calls 7

newFunction · 0.85
take_numeric_paramFunction · 0.85
strip_prefixMethod · 0.80
is_emptyMethod · 0.45
pushMethod · 0.45
lenMethod · 0.45

Tested by

no test coverage detected