fix: Properly parse Expressions, Idents, and Literals

This commit is contained in:
2025-01-11 11:16:23 -05:00
parent 295623efb2
commit ebc4cc0bd4
4 changed files with 80 additions and 9 deletions

View File

@@ -27,3 +27,9 @@ perf = "deny"
style = "deny"
nursery = "deny"
pedantic = "deny"
[package.metadata.release]
pre-release-hook = ["git", "cliff", "-o", "CHANGELOG.md", "--tag", "{{version}}"]
pre-release-replacements = [
{ file = "README.md", search = "comlexr = \"\\d+.\\d+.\\d+\"", replace = "comlexr = \"{{version}}\"" }
]

61
justfile Normal file
View File

@@ -0,0 +1,61 @@
export RUST_BACKTRACE := "1"
set dotenv-load := true
set positional-arguments := true
# default recipe to display help information
default:
@just --list
# Clean up development files and images
clean:
cargo clean
# Run unit tests
test:
cargo test --workspace -- --show-output
# Run unit tests for all features
test-all-features:
cargo test --workspace --all-features -- --show-output
# Run clippy
lint:
cargo clippy
# Run clippy for all features
lint-all-features:
cargo clippy --all-features
# Expand the macros of a module for debugging
expand *args:
cargo expand $@ > ./expand.rs
$EDITOR ./expand.rs
# Installs cargo tools that help with development
tools:
rustup toolchain install stable nightly
rustup component add --toolchain stable rust-analyzer clippy rustfmt
cargo install --locked cargo-watch cargo-expand bacon
# Run cargo release and push the tag separately
release *args:
#!/usr/bin/env bash
set -euxo pipefail
earthly --ci +run-checks
# --workspace: updating all crates in the workspace
# --no-tag: do not push tag for each new version
# --no-confirm: don't look for user input, just run the command
# --execute: not a dry run
cargo release $1 -v \
--workspace \
--no-tag \
--no-confirm \
--execute
VERSION=$(cargo metadata --format-version 1 | jq -r '.packages[] | select(.name == "comlexr") .version')
echo "Pushing tag: v${VERSION}"
git tag "v${VERSION}"
git push origin "v${VERSION}"

View File

@@ -374,13 +374,17 @@ enum Value {
impl Parse for Value {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
if input.peek(syn::Lit) {
input.parse().map(Self::Lit)
} else if input.peek(syn::Ident) {
input.parse().map(Self::Ident)
} else {
input.parse().map(Self::Expr)
}
let expr_fork = input.fork();
expr_fork
.parse::<syn::Expr>()
.and_then(|_| input.parse().map(Self::Expr))
.or_else(|_| {
let ident_fork = input.fork();
ident_fork
.parse::<syn::Ident>()
.and_then(|_| input.parse().map(Self::Ident))
})
.or_else(|_| input.parse().map(Self::Lit))
}
}

View File

@@ -109,7 +109,7 @@ fn match_statement(#[case] match_arg: TestArgs, #[case] expected: &str) {
#[case(None, None, r#""echo" "test""#)]
#[case(Some("arg"), None, r#""echo" "test" "arg""#)]
#[case(None, Some("arg"), r#""echo" "test" "multi" "arg""#)]
#[case(Some("1"), Some("2"), r#""echo" "test" "1" "multi" "2""#)]
#[case(Some("1"), Some("2"), r#""echo" "test" "1" "multi=2""#)]
fn multi_match(#[case] single: Option<&str>, #[case] multi: Option<&str>, #[case] expected: &str) {
let command = cmd!(
"echo",
@@ -118,7 +118,7 @@ fn multi_match(#[case] single: Option<&str>, #[case] multi: Option<&str>, #[case
(None, None) => [],
(Some(single), None) => single,
(None, Some(multi)) => ["multi", multi],
(Some(single), Some(multi)) => [single, "multi", multi],
(Some(single), Some(multi)) => [single, format!("multi={multi}")],
},
);