Skip to content

Commit

Permalink
Remove TryFrom<proc_macro::Literal> impl for BoolLit
Browse files Browse the repository at this point in the history
It does not make sense and would always fail.
  • Loading branch information
LukasKalbertodt committed May 28, 2021
1 parent e7d7b4b commit 966f6cc
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 36 deletions.
65 changes: 35 additions & 30 deletions src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,12 @@ macro_rules! impl_for_specific_lit {
type Error = InvalidToken;
fn try_from(tt: $($prefix)* TokenTree) -> Result<Self, Self::Error> {
let span = tt.span();
let res = impl_for_specific_lit!(@token_match [$($prefix)*] $variant tt);
let res = match tt {
$($prefix)* TokenTree::Group(_) => Err(TokenKind::Group),
$($prefix)* TokenTree::Punct(_) => Err(TokenKind::Punct),
$($prefix)* TokenTree::Ident(_) => Err(TokenKind::Ident),
$($prefix)* TokenTree::Literal(ref lit) => Ok(lit),
};

match res {
Ok(lit) => <$ty>::try_from(lit),
Expand All @@ -151,38 +156,44 @@ macro_rules! impl_for_specific_lit {
}
}
};

// In case we are implementing it for `BoolLit`, we need to check for two extra cases.
(@token_match [$($prefix:tt)*] Bool $tt:ident) => {
match $tt {
$($prefix)* TokenTree::Group(_) => Err(TokenKind::Group),
$($prefix)* TokenTree::Punct(_) => Err(TokenKind::Punct),
$($prefix)* TokenTree::Ident(ref ident) if ident.to_string() == "true"
=> return Ok(crate::BoolLit::True),
$($prefix)* TokenTree::Ident(ref ident) if ident.to_string() == "false"
=> return Ok(crate::BoolLit::False),
$($prefix)* TokenTree::Ident(_) => Err(TokenKind::Ident),
$($prefix)* TokenTree::Literal(ref lit) => Ok(lit),
}
};
(@token_match [$($prefix:tt)*] $other:ident $tt:ident) => {
match $tt {
$($prefix)* TokenTree::Group(_) => Err(TokenKind::Group),
$($prefix)* TokenTree::Punct(_) => Err(TokenKind::Punct),
$($prefix)* TokenTree::Ident(_) => Err(TokenKind::Ident),
$($prefix)* TokenTree::Literal(ref lit) => Ok(lit),
}
};
}

helper!(impl_for_specific_lit, crate::BoolLit, Bool, BoolLit);
helper!(impl_for_specific_lit, crate::IntegerLit<String>, Integer, IntegerLit);
helper!(impl_for_specific_lit, crate::FloatLit<String>, Float, FloatLit);
helper!(impl_for_specific_lit, crate::CharLit<String>, Char, CharLit);
helper!(impl_for_specific_lit, crate::StringLit<String>, String, StringLit);
helper!(impl_for_specific_lit, crate::ByteLit<String>, Byte, ByteLit);
helper!(impl_for_specific_lit, crate::ByteStringLit<String>, ByteString, ByteStringLit);

macro_rules! impl_from_tt_for_bool {
([$($prefix:tt)*] => ) => {
impl TryFrom<$($prefix)* TokenTree> for crate::BoolLit {
type Error = InvalidToken;
fn try_from(tt: $($prefix)* TokenTree) -> Result<Self, Self::Error> {
let span = tt.span();
let actual = match tt {
$($prefix)* TokenTree::Ident(ref ident) if ident.to_string() == "true"
=> return Ok(crate::BoolLit::True),
$($prefix)* TokenTree::Ident(ref ident) if ident.to_string() == "false"
=> return Ok(crate::BoolLit::False),

$($prefix)* TokenTree::Group(_) => TokenKind::Group,
$($prefix)* TokenTree::Punct(_) => TokenKind::Punct,
$($prefix)* TokenTree::Ident(_) => TokenKind::Ident,
$($prefix)* TokenTree::Literal(ref lit) => kind_of(&Literal::from(lit)),
};

Err(InvalidToken {
actual,
expected: TokenKind::BoolLit,
span: span.into(),
})
}
}
};
}

helper!(impl_from_tt_for_bool, );


mod tests {
Expand Down Expand Up @@ -222,9 +233,6 @@ mod tests {
//! let _ = litrs::Literal::try_from(give::<&proc_macro::TokenTree>());
//!
//!
//! let _ = litrs::BoolLit::try_from(give::<proc_macro::Literal>());
//! let _ = litrs::BoolLit::try_from(give::<&proc_macro::Literal>());
//!
//! let _ = litrs::IntegerLit::try_from(give::<proc_macro::Literal>());
//! let _ = litrs::IntegerLit::try_from(give::<&proc_macro::Literal>());
//!
Expand Down Expand Up @@ -288,9 +296,6 @@ mod tests_proc_macro2 {
//! let _ = litrs::Literal::try_from(give::<&proc_macro2::TokenTree>());
//!
//!
//! let _ = litrs::BoolLit::try_from(give::<proc_macro2::Literal>());
//! let _ = litrs::BoolLit::try_from(give::<&proc_macro2::Literal>());
//!
//! let _ = litrs::IntegerLit::try_from(give::<proc_macro2::Literal>());
//! let _ = litrs::IntegerLit::try_from(give::<&proc_macro2::Literal>());
//!
Expand Down
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@
//!
//! **Note**: `true` and `false` are `Ident`s when passed to your proc macro.
//! The `TryFrom<TokenTree>` impls check for those two special idents and
//! return a `BoolLit` appropriately.
//! return a `BoolLit` appropriately. For that reason, there is also no
//! `TryFrom<proc_macro::Literal>` impl for `BoolLit`. The `proc_macro::Literal`
//! simply cannot represent bool literals.
//!
//!
//! # Examples
Expand Down
12 changes: 7 additions & 5 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ fn proc_macro() {
use proc_macro2::{
self as pm2, TokenTree, Group, TokenStream, Delimiter, Spacing, Punct, Span, Ident,
};
use crate::{BoolLit, ByteStringLit, CharLit, FloatLit, IntegerLit, StringLit, err::TokenKind};
use crate::{
BoolLit, ByteLit, ByteStringLit, CharLit, FloatLit, IntegerLit, StringLit, err::TokenKind
};


macro_rules! assert_invalid_token {
Expand Down Expand Up @@ -189,13 +191,13 @@ fn proc_macro() {
actual: TokenKind::FloatLit,
);
assert_invalid_token!(
BoolLit::try_from(pm_bytestr_lit.clone()),
expected: TokenKind::BoolLit,
ByteLit::try_from(pm_bytestr_lit.clone()),
expected: TokenKind::ByteLit,
actual: TokenKind::ByteStringLit,
);
assert_invalid_token!(
BoolLit::try_from(pm_i16_lit.clone()),
expected: TokenKind::BoolLit,
ByteLit::try_from(pm_i16_lit.clone()),
expected: TokenKind::ByteLit,
actual: TokenKind::IntegerLit,
);
assert_invalid_token!(
Expand Down

0 comments on commit 966f6cc

Please sign in to comment.