added initial implementation of self defining expressions to fstring (Python3.8)

This commit is contained in:
TheAnyKey
2020-04-28 18:41:17 -04:00
parent b4c28ad351
commit 94a7b48560

View File

@@ -26,6 +26,7 @@ impl<'a> FStringParser<'a> {
let mut spec = None;
let mut delims = Vec::new();
let mut conversion = None;
let mut pred_expression_text = String::new();
while let Some(ch) = self.chars.next() {
match ch {
@@ -50,6 +51,13 @@ impl<'a> FStringParser<'a> {
return Err(ExpectedRbrace);
}
}
// match a python 3.8 self documenting expression
// format '{' PYTHON_EXPRESSION '=' FORMAT_SPECIFIER? '}'
'=' if self.chars.peek() != Some(&'=') => {
pred_expression_text = expression.trim().to_string(); // use expression and remove whitespace
}
':' if delims.is_empty() => {
let mut nested = false;
let mut in_nested = false;
@@ -121,14 +129,34 @@ impl<'a> FStringParser<'a> {
if expression.is_empty() {
return Err(EmptyExpression);
}
return Ok(FormattedValue {
value: Box::new(
parse_expression(expression.trim())
.map_err(|e| InvalidExpression(Box::new(e.error)))?,
),
conversion,
spec,
});
if pred_expression_text.is_empty() {
return Ok(FormattedValue {
value: Box::new(
parse_expression(expression.trim())
.map_err(|e| InvalidExpression(Box::new(e.error)))?,
),
conversion,
spec,
});
}
else {
return Ok(Joined{
values:vec![
Constant{
value:pred_expression_text.to_owned()
},
FormattedValue {
value: Box::new(
parse_expression(expression.trim())
.map_err(|e| InvalidExpression(Box::new(e.error)))?,
),
conversion,
spec,},
]
}
);
}
}
'"' | '\'' => {
expression.push(ch);
@@ -298,6 +326,30 @@ mod tests {
);
}
#[test]
fn test_fstring_parse_selfdocumenting_base() {
let src=String::from("{user=}");
let parse_ast=parse_fstring(&src);
assert!(parse_ast.is_ok());
}
#[test]
fn test_fstring_parse_selfdocumenting_base_more() {
let src=String::from("mix {user=} with text and {second=}");
let parse_ast=parse_fstring(&src);
assert!(parse_ast.is_ok());
}
#[test]
fn test_fstring_parse_selfdocumenting_format() {
let src=String::from("{user=:>10}");
let parse_ast=parse_fstring(&src);
assert!(parse_ast.is_ok());
}
#[test]
fn test_parse_invalid_fstring() {
assert_eq!(parse_fstring("{5!a"), Err(ExpectedRbrace));
@@ -318,6 +370,10 @@ mod tests {
assert_eq!(parse_fstring("{a:{b}"), Err(UnclosedLbrace));
assert_eq!(parse_fstring("{"), Err(UnclosedLbrace));
// TODO: which err?
//assert_eq!(parse_fstring("{}"), Err()); // which one?
assert!(parse_fstring("{}").is_err()); // take this for the moment
// TODO: check for InvalidExpression enum?
assert!(parse_fstring("{class}").is_err());
}