Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement vars, choose/when, and expressions #32

Open
wants to merge 46 commits into
base: main
Choose a base branch
from
Open

Conversation

tyler
Copy link
Member

@tyler tyler commented Dec 4, 2024

  • Basic variable assignment (esi:assign)
  • Short form esi:vars
  • Long form esi:vars
  • Expression parsing and evaluation
  • esi:choose & esi:when
    • parse
    • interpret
  • matches operator
    • also matches_i
    • implement regex matching
    • expose captures (requires map vars)
    • respect matchname parameter
  • triple tick strings
  • minimal stdlib
    • function calls
    • implement library calls
      • lower
      • html_encode
      • replace
  • map variables
  • request metadata
    • host, method, querystring
    • headers in general? (what else is needed here in the short term?)

Cleanup tasks

  • revamp the parser to identify expressions in raw text (I think this is ultimately a separate parser from the expression parser. They're similar but not identical.)
  • identify function calls correctly (i.e. $fn($(var), ...) is valid in raw text ESI contexts
  • make sure we're interpolating in the right contexts (i.e. inside a vars, when, try, long form assign, etc) and not others
  • refactor EvalContext and Variables
  • differentiate interpreter errors (they all come out as Parse errors right now)
  • make the messages in those interp errors actually useful
  • make sure errors in the interpreter all bubble out of Value::Error, rather than real errors
    • returning a Value::Error should log, but otherwise be interpreted as a Null (I think?!)
  • fix all todo!() calls

@tyler tyler changed the title Implement ESI Vars Implement a vars, choose/when, and expressions Dec 5, 2024
@tyler tyler changed the title Implement a vars, choose/when, and expressions Implement vars, choose/when, and expressions Dec 5, 2024
@tyler tyler marked this pull request as ready for review December 10, 2024 21:34
vagetman
vagetman previously approved these changes Dec 15, 2024
Copy link
Member

@kailan kailan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really pleased with this, thanks so much both for your hard work and for your patience while I get it reviewed. Just a few areas to address in regards to error handling but I'm happy for this to be released once the printlns are gone.

Comment on lines 100 to 111
fn do_parse<'a, R>(
reader: &mut Reader<R>,
callback: &mut dyn FnMut(Event<'a>) -> Result<()>,
task: &mut Vec<Event<'a>>,
depth: &mut usize,
use_queue: bool,
try_depth: &mut usize,
choose_depth: &mut usize,
current_arm: &mut Option<TryTagArms>,
tag: &TagNames,
content_type: &ContentType,
) -> Result<()>
where
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function signature is getting pretty complex but we can leave it for now as it's not part of the public API surface and there is a parser rework in progress.

Comment on lines +438 to +449
.attributes()
.flatten()
.find(|attr| attr.key.into_inner() == b"name")
{
Some(attr) => String::from_utf8(attr.value.to_vec()).unwrap(),
None => {
return Err(ExecutionError::MissingRequiredParameter(
String::from_utf8(elem.name().into_inner().to_vec()).unwrap(),
"name".to_string(),
));
}
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This parsing pattern appears a few times in this file but, again, we can leave that for the parser rework.

@@ -504,7 +517,97 @@ fn event_receiver(
except_task,
});
}
Event::XML(event) => {
Event::ESI(Tag::Assign { name, value }) => {
// TODO: the 'name' here might have a subfield, we need to parse it
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this something that needs to be addressed before release?

}
}
Event::ESI(Tag::When { .. }) => {
println!("Shouldn't be possible to get a When tag here");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this throw an error?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If not we should at least avoid println and use the logging macros.

break;
}
} else {
println!("Somehow got something other than a When in a Choose: {when:?}",);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error?

}

#[cfg(test)]
mod tests {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests are a large part of this file, I wonder if it's worth extracting them into the tests directory.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a blocker

) -> Option<Value> {
evaluate_interpolated(cur, ctx)
.map_err(|e| {
println!("Error while evaluating interpolated expression: {e}");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this throw an error?
Avoid println

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants