Skip to content

Use the uguid crate to replace the Guid struct and guid! macro #777

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

Merged
merged 1 commit into from
Apr 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@
`Status`. `impl From<Status> for Result` has also been removed. A new
`StatusExt` trait has been added that provides conversion methods to replace
the ones that have been removed. `StatusExt` has been added to the prelude.
- The `Guid` struct and `guid!` macro implementations have been replaced with
re-exports from the [`uguid`](https://docs.rs/uguid) crate. The `from_values`
method has been removed; usually the `guid!` macro is a more convenient
choice, but `new` or `from_bytes` can also be used if needed. There are also a
number of new `Guid` methods.

## uefi-macros - [Unreleased]

Expand Down
56 changes: 7 additions & 49 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion uefi-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,4 @@ quote = "1.0.9"
syn = { version = "2.0.4", features = ["full"] }

[dev-dependencies]
trybuild = "1.0.61"
uefi = { version = "0.20.0", default-features = false }
102 changes: 3 additions & 99 deletions uefi-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ extern crate proc_macro;

use proc_macro::TokenStream;

use proc_macro2::{TokenStream as TokenStream2, TokenTree};
use quote::{quote, quote_spanned, ToTokens, TokenStreamExt};
use proc_macro2::TokenStream as TokenStream2;
use quote::{quote, quote_spanned, TokenStreamExt};
use syn::spanned::Spanned;
use syn::{
parse_macro_input, parse_quote, Error, Expr, ExprLit, ExprPath, FnArg, Ident, ItemFn,
Expand Down Expand Up @@ -64,19 +64,7 @@ pub fn unsafe_protocol(args: TokenStream, input: TokenStream) -> TokenStream {
Expr::Lit(ExprLit {
lit: Lit::Str(lit), ..
}) => {
// Parse as a GUID string.
let (time_low, time_mid, time_high_and_version, clock_seq_and_variant, node) =
match parse_guid(lit) {
Ok(data) => data,
Err(tokens) => return tokens.into(),
};
quote!(::uefi::Guid::from_values(
#time_low,
#time_mid,
#time_high_and_version,
#clock_seq_and_variant,
#node,
))
quote!(::uefi::guid!(#lit))
}
Expr::Path(ExprPath { path, .. }) => quote!(#path),
_ => {
Expand Down Expand Up @@ -111,90 +99,6 @@ pub fn unsafe_protocol(args: TokenStream, input: TokenStream) -> TokenStream {
.into()
}

/// Create a `Guid` at compile time.
///
/// # Example
///
/// ```
/// use uefi::{guid, Guid};
/// const EXAMPLE_GUID: Guid = guid!("12345678-9abc-def0-1234-56789abcdef0");
/// ```
#[proc_macro]
pub fn guid(args: TokenStream) -> TokenStream {
let (time_low, time_mid, time_high_and_version, clock_seq_and_variant, node) =
match parse_guid(parse_macro_input!(args as LitStr)) {
Ok(data) => data,
Err(tokens) => return tokens.into(),
};

quote!({
const g: ::uefi::Guid = ::uefi::Guid::from_values(
#time_low,
#time_mid,
#time_high_and_version,
#clock_seq_and_variant,
#node,
);
g
})
.into()
}

fn parse_guid(guid_lit: LitStr) -> Result<(u32, u16, u16, u16, u64), TokenStream2> {
let guid_str = guid_lit.value();

// We expect a canonical GUID string, such as "12345678-9abc-def0-fedc-ba9876543210"
if guid_str.len() != 36 {
return Err(err!(
guid_lit,
"\"{}\" is not a canonical GUID string (expected 36 bytes, found {})",
guid_str,
guid_str.len()
));
}
let mut offset = 1; // 1 is for the starting quote
let mut guid_hex_iter = guid_str.split('-');
let mut next_guid_int = |len: usize| -> Result<u64, TokenStream2> {
let guid_hex_component = guid_hex_iter.next().unwrap();

// convert syn::LitStr to proc_macro2::Literal..
let lit = match guid_lit.to_token_stream().into_iter().next().unwrap() {
TokenTree::Literal(lit) => lit,
_ => unreachable!(),
};
// ..so that we can call subspan and nightly users (us) will get the fancy span
let span = lit
.subspan(offset..offset + guid_hex_component.len())
.unwrap_or_else(|| lit.span());

if guid_hex_component.len() != len * 2 {
return Err(err!(
span,
"GUID component \"{}\" is not a {}-bit hexadecimal string",
guid_hex_component,
len * 8
));
}
offset += guid_hex_component.len() + 1; // + 1 for the dash
u64::from_str_radix(guid_hex_component, 16).map_err(|_| {
err!(
span,
"GUID component \"{}\" is not a hexadecimal number",
guid_hex_component
)
})
};

// The GUID string is composed of a 32-bit integer, three 16-bit ones, and a 48-bit one
Ok((
next_guid_int(4)? as u32,
next_guid_int(2)? as u16,
next_guid_int(2)? as u16,
next_guid_int(2)? as u16,
next_guid_int(6)?,
))
}

/// Get the name of a function's argument at `arg_index`.
fn get_function_arg_name(f: &ItemFn, arg_index: usize, errors: &mut TokenStream2) -> Option<Ident> {
if let Some(FnArg::Typed(arg)) = f.sig.inputs.iter().nth(arg_index) {
Expand Down
5 changes: 0 additions & 5 deletions uefi-macros/tests/compilation.rs

This file was deleted.

10 changes: 0 additions & 10 deletions uefi-macros/tests/ui/entry_bad_abi.rs

This file was deleted.

5 changes: 0 additions & 5 deletions uefi-macros/tests/ui/entry_bad_abi.stderr

This file was deleted.

10 changes: 0 additions & 10 deletions uefi-macros/tests/ui/entry_bad_arg.rs

This file was deleted.

8 changes: 0 additions & 8 deletions uefi-macros/tests/ui/entry_bad_arg.stderr

This file was deleted.

10 changes: 0 additions & 10 deletions uefi-macros/tests/ui/entry_bad_async.rs

This file was deleted.

5 changes: 0 additions & 5 deletions uefi-macros/tests/ui/entry_bad_async.stderr

This file was deleted.

10 changes: 0 additions & 10 deletions uefi-macros/tests/ui/entry_bad_attr_arg.rs

This file was deleted.

5 changes: 0 additions & 5 deletions uefi-macros/tests/ui/entry_bad_attr_arg.stderr

This file was deleted.

10 changes: 0 additions & 10 deletions uefi-macros/tests/ui/entry_bad_const.rs

This file was deleted.

5 changes: 0 additions & 5 deletions uefi-macros/tests/ui/entry_bad_const.stderr

This file was deleted.

10 changes: 0 additions & 10 deletions uefi-macros/tests/ui/entry_bad_generic.rs

This file was deleted.

5 changes: 0 additions & 5 deletions uefi-macros/tests/ui/entry_bad_generic.stderr

This file was deleted.

10 changes: 0 additions & 10 deletions uefi-macros/tests/ui/entry_bad_return_type.rs

This file was deleted.

8 changes: 0 additions & 8 deletions uefi-macros/tests/ui/entry_bad_return_type.stderr

This file was deleted.

10 changes: 0 additions & 10 deletions uefi-macros/tests/ui/entry_unnamed_image_arg.rs

This file was deleted.

5 changes: 0 additions & 5 deletions uefi-macros/tests/ui/entry_unnamed_image_arg.stderr

This file was deleted.

Loading