Merge remote-tracking branch 'origin/macro/qualified'

* origin/macro/qualified:
  git-ref-format: qualified macro
This commit is contained in:
Fintan Halpenny
2022-10-13 09:21:07 +01:00
3 changed files with 65 additions and 2 deletions
+47 -1
View File
@@ -13,7 +13,7 @@ use proc_macro_error::abort;
use quote::quote;
use syn::{parse_macro_input, LitStr};
use git_ref_format_core::{refspec::PatternStr, Component, Error, RefStr};
use git_ref_format_core::{refspec::PatternStr, Component, Error, Qualified, RefStr};
/// Create a [`git_ref_format_core::RefString`] from a string literal.
///
@@ -46,6 +46,52 @@ pub fn refname(input: TokenStream) -> TokenStream {
}
}
/// Create a [`git_ref_format_core::Qualified`] from a string literal.
///
/// The string is validated at compile time, and an unsafe conversion is
/// emitted.
#[proc_macro_error]
#[proc_macro]
pub fn qualified(input: TokenStream) -> TokenStream {
let lit = parse_macro_input!(input as LitStr);
let val = lit.value();
let parsed: Result<&RefStr, Error> = val.as_str().try_into();
match parsed {
Ok(name) => {
let qualified: Option<Qualified> = Qualified::from_refstr(name);
match qualified {
Some(safe) => {
let safe: &str = safe.as_str();
let expand = quote! {
unsafe {
use ::std::{borrow::Cow, mem::transmute};
use ::git_ref_format::{Component, RefStr, RefString};
let inner: RefString = transmute(#safe.to_owned());
let cow: Cow<'static, RefStr> = Cow::Owned(inner);
transmute::<_, Qualified>(cow)
}
};
TokenStream::from(expand)
},
None => {
abort!(
lit.span(),
"refname is not of the form 'refs/<category>/<name>'"
);
},
}
},
Err(e) => {
abort!(lit.span(), "invalid refname literal: {}", e);
},
}
}
/// Create a [`git_ref_format_core::Component`] from a string literal.
///
/// The string is validated at compile time, and an unsafe conversion is
+2
View File
@@ -144,6 +144,8 @@ pub mod name {
pub use git_ref_format_macro::component;
}
#[cfg(any(feature = "macro", feature = "git-ref-format-macro"))]
pub use git_ref_format_macro::qualified;
#[cfg(any(feature = "macro", feature = "git-ref-format-macro"))]
pub use git_ref_format_macro::refname;
+16 -1
View File
@@ -1,13 +1,28 @@
// Copyright © 2022 The Radicle Link Contributors
// SPDX-License-Identifier: GPL-3.0-or-later
use git_ref_format::{component, name, refname, refspec, Error, Qualified, RefStr, RefString};
use git_ref_format::{
component,
name,
qualified,
refname,
refspec,
Error,
Qualified,
RefStr,
RefString,
};
#[test]
fn refname_macro_works() {
assert_eq!("refs/heads/main", refname!("refs/heads/main").as_str())
}
#[test]
fn qualified_macro_works() {
assert_eq!("refs/heads/main", qualified!("refs/heads/main").as_str())
}
#[test]
fn component_macro_works() {
assert_eq!("self", name::component!("self").as_str())