uuid-rs / uuid

Generate and parse UUIDs.
https://www.crates.io/crates/uuid
Other
1.01k stars 192 forks source link

Use const identifier in uuid macro #764

Closed Vrajs16 closed 4 months ago

Vrajs16 commented 4 months ago

The code below works when the user doesn't enable macro-diagnostics feature.

It's not possible to convert the value of identifier into a string literal at compile time, but is there another way we can go about this so we can give more details when this feature is enabled.

If not, we can just paste the same code inside the macro where macro-diagnostics is enabled so that at least there wouldn't be a compile time error.

($uuid:ident) => {{
    const OUTPUT: $crate::Uuid = match $crate::Uuid::try_parse($uuid) {
        $crate::__macro_support::Ok(u) => u,
        $crate::__macro_support::Err(_) => panic!("invalid UUID"),
    };
    OUTPUT
}};

Closes #756

KodrAus commented 4 months ago

Thanks @Vrajs16! We should be able to support this in the procedural macro too by modifying this block here: https://github.com/uuid-rs/uuid/blob/main/macros/src/lib.rs#L70-L83.

We'd change it to parse a syn::Expr instead of a syn::Lit. If we match a syn::ExprLit { lit: syn::Lit::Str(str) } from that expression then we'd follow the old path that parses the string, otherwise we generate the same code as what you're doing in the macro_rules macro.

Is this something you'd like to take a shot at implementing? If not, I'll be happy to merge this change once it passes CI and update the macros myself.

Vrajs16 commented 4 months ago

Hi @KodrAus, not sure how I would generate the same the code in build_uuid function. I was thinking, when a user puts a variable inside the uuid! macro, macro rules will match ($uuid:ident) => ... and then we just use the same code as the below:

const OUTPUT: $crate::Uuid = match $crate::Uuid::try_parse($uuid) { 
    $crate::__macro_support::Ok(u) => u,
    $crate::__macro_support::Err(_) => panic!("invalid UUID"),
};
OUTPUT
KodrAus commented 4 months ago

Ah, sorry I'd forgotten we still wrap the procedural macro in a regular macro-rules one. Duplicating the match arm in the case where macro-diagnostics is enabled should be all we need.