Skip to content

Commit

Permalink
Merge pull request #13 from B-Reif/remove-rustfmt
Browse files Browse the repository at this point in the history
Remove rustfmt
  • Loading branch information
MrGVSV authored Mar 7, 2022
2 parents 2d2d6a7 + ff51066 commit 22c84e3
Show file tree
Hide file tree
Showing 15 changed files with 1,120 additions and 1,128 deletions.
102 changes: 51 additions & 51 deletions bevy_proto_derive/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,62 +7,62 @@ use crate::constants::{INTO_IDENT, WITH_IDENT};

/// ProtoComponent attributes applied on structs
pub(crate) enum ProtoCompAttr {
/// Captures the `#[proto_comp(into = "ActualComponent")]` attribute
///
/// This is used to specify a separate Component that this marked struct will be cloned into.
///
/// Generates the following code:
/// ```rust
/// let component: ActualComponent = self.clone().into();
/// commands.insert(component);
/// ```
Into(Ident),
/// Captures the `#[proto_comp(with = "my_function")]` attribute
///
/// This is used to specify a custom function with which custom Components will be creatde and/or inserted.
/// This is essentially identical to just simply implementing `ProtoComponent` yourself.
///
/// Generates the following code:
/// ```rust
/// my_function(self, commands, asset_server);
/// ```
With(Ident),
/// Captures the `#[proto_comp(into = "ActualComponent")]` attribute
///
/// This is used to specify a separate Component that this marked struct will be cloned into.
///
/// Generates the following code:
/// ```rust
/// let component: ActualComponent = self.clone().into();
/// commands.insert(component);
/// ```
Into(Ident),
/// Captures the `#[proto_comp(with = "my_function")]` attribute
///
/// This is used to specify a custom function with which custom Components will be creatde and/or inserted.
/// This is essentially identical to just simply implementing `ProtoComponent` yourself.
///
/// Generates the following code:
/// ```rust
/// my_function(self, commands, asset_server);
/// ```
With(Ident),
}

impl Parse for ProtoCompAttr {
fn parse(input: ParseStream) -> Result<Self> {
let path: Path = input.parse()?;
let _: Token![=] = input.parse()?;
let item: LitStr = input.parse()?;
let ident = format_ident!("{}", item.value());
fn parse(input: ParseStream) -> Result<Self> {
let path: Path = input.parse()?;
let _: Token![=] = input.parse()?;
let item: LitStr = input.parse()?;
let ident = format_ident!("{}", item.value());

if path == WITH_IDENT {
Ok(Self::With(ident))
} else if path == INTO_IDENT {
Ok(Self::Into(ident))
} else {
Err(Error::new(Span::call_site(), "Unexpected path"))
}
}
if path == WITH_IDENT {
Ok(Self::With(ident))
} else if path == INTO_IDENT {
Ok(Self::Into(ident))
} else {
Err(Error::new(Span::call_site(), "Unexpected path"))
}
}
}

impl ToTokens for ProtoCompAttr {
fn to_tokens(&self, tokens: &mut TokenStream) {
match self {
Self::Into(ident) => {
let into_ident = quote! {
let cloned = self.clone();
let component: #ident = cloned.into();
commands.insert(component);
};
into_ident.to_tokens(tokens);
}
Self::With(ident) => {
let with_ident = quote! {
#ident(self, commands, asset_server);
};
with_ident.to_tokens(tokens);
}
}
}
fn to_tokens(&self, tokens: &mut TokenStream) {
match self {
Self::Into(ident) => {
let into_ident = quote! {
let cloned = self.clone();
let component: #ident = cloned.into();
commands.insert(component);
};
into_ident.to_tokens(tokens);
}
Self::With(ident) => {
let with_ident = quote! {
#ident(self, commands, asset_server);
};
with_ident.to_tokens(tokens);
}
}
}
}
12 changes: 6 additions & 6 deletions bevy_proto_derive/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
pub(crate) struct Symbol(&'static str);

impl<'a> PartialEq<Symbol> for &'a syn::Path {
fn eq(&self, ident: &Symbol) -> bool {
self.is_ident(ident.0)
}
fn eq(&self, ident: &Symbol) -> bool {
self.is_ident(ident.0)
}
}

impl PartialEq<Symbol> for syn::Path {
fn eq(&self, ident: &Symbol) -> bool {
self.is_ident(ident.0)
}
fn eq(&self, ident: &Symbol) -> bool {
self.is_ident(ident.0)
}
}

pub(crate) const WITH_IDENT: Symbol = Symbol("with");
Expand Down
82 changes: 41 additions & 41 deletions bevy_proto_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,49 +41,49 @@ mod constants;
/// ```
#[proc_macro_derive(ProtoComponent, attributes(proto_comp))]
pub fn proto_comp_derive(input: TokenStream) -> TokenStream {
let DeriveInput {
ident, data, attrs, ..
} = parse_macro_input!(input);
let DeriveInput {
ident, data, attrs, ..
} = parse_macro_input!(input);

let mut generator = None;
for attr in attrs {
let struct_attr: Result<ProtoCompAttr> = attr.parse_args();
if let Ok(struct_attr) = struct_attr {
generator = Some(quote! { #struct_attr });
break;
}
}
let mut generator = None;
for attr in attrs {
let struct_attr: Result<ProtoCompAttr> = attr.parse_args();
if let Ok(struct_attr) = struct_attr {
generator = Some(quote! { #struct_attr });
break;
}
}

let generator = if let Some(generator) = generator {
generator
} else {
match data {
Data::Struct(..) | Data::Enum(..) => {
quote! {
let component = self.clone();
commands.insert(component);
}
}
_ => syn::Error::new(
Span::call_site(),
"ProtoComponent can only be applied on struct types",
)
.to_compile_error(),
}
};
let generator = if let Some(generator) = generator {
generator
} else {
match data {
Data::Struct(..) | Data::Enum(..) => {
quote! {
let component = self.clone();
commands.insert(component);
}
}
_ => syn::Error::new(
Span::call_site(),
"ProtoComponent can only be applied on struct types",
)
.to_compile_error(),
}
};

let output = quote! {
#[typetag::serde]
impl bevy_proto::prelude::ProtoComponent for #ident {
fn insert_self(
&self,
commands: &mut bevy_proto::prelude::ProtoCommands,
asset_server: &bevy::prelude::Res<bevy::prelude::AssetServer>,
) {
#generator;
}
}
};
let output = quote! {
#[typetag::serde]
impl bevy_proto::prelude::ProtoComponent for #ident {
fn insert_self(
&self,
commands: &mut bevy_proto::prelude::ProtoCommands,
asset_server: &bevy::prelude::Res<bevy::prelude::AssetServer>,
) {
#generator;
}
}
};

output.into()
output.into()
}
84 changes: 42 additions & 42 deletions examples/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,90 +23,90 @@ struct Emoji(String);
#[derive(Clone, Serialize, Deserialize, ProtoComponent)]
#[proto_comp(into = "Emoji")]
struct EmojiDef {
emoji: String,
emoji: String,
}

/// Make sure you impl `From<T>`!
impl From<EmojiDef> for Emoji {
fn from(def: EmojiDef) -> Self {
Self(def.emoji)
}
fn from(def: EmojiDef) -> Self {
Self(def.emoji)
}
}

/// Alternatively, you might want or have a function that performs the spawn logic that should
/// be shared so that it may be used in other places or for other components.
///
/// Say we have a trait that allows its implementors to return an `Emoji` struct.
trait AsEmoji {
fn as_emoji(&self) -> Emoji;
fn as_emoji(&self) -> Emoji;
}

/// We can create a function that takes any `ProtoComponent` that implements `AsEmoji` and inserts
/// an `Emoji` component.
fn create_emoji<T: AsEmoji + ProtoComponent>(
component: &T,
commands: &mut ProtoCommands,
_asset_server: &Res<AssetServer>,
component: &T,
commands: &mut ProtoCommands,
_asset_server: &Res<AssetServer>,
) {
commands.insert(component.as_emoji());
commands.insert(component.as_emoji());
}

/// Then we can use the `#[proto_comp(with = "my_function")]` attribute. This works exactly
/// like [`ProtoComponent::insert_self`], but allows you to use an extracted version of that function.
#[derive(Clone, Serialize, Deserialize, ProtoComponent)]
#[proto_comp(with = "create_emoji")]
enum Mood {
Normal,
Silly,
Normal,
Silly,
}
impl AsEmoji for Mood {
fn as_emoji(&self) -> Emoji {
match self {
Self::Normal => Emoji(String::from("😶")),
Self::Silly => Emoji(String::from("🤪")),
}
}
fn as_emoji(&self) -> Emoji {
match self {
Self::Normal => Emoji(String::from("😶")),
Self::Silly => Emoji(String::from("🤪")),
}
}
}

/// Notice that we only had to define the function once even though we're using it across multiple
/// `ProtoComponent` structs.
#[derive(Clone, Serialize, Deserialize, ProtoComponent)]
#[proto_comp(with = "create_emoji")]
enum Face {
Normal,
Frowning,
Normal,
Frowning,
}
impl AsEmoji for Face {
fn as_emoji(&self) -> Emoji {
match self {
Self::Normal => Emoji(String::from("😶")),
Self::Frowning => Emoji(String::from("😠")),
}
}
fn as_emoji(&self) -> Emoji {
match self {
Self::Normal => Emoji(String::from("😶")),
Self::Frowning => Emoji(String::from("😠")),
}
}
}

fn spawn_emojis(mut commands: Commands, data: Res<ProtoData>, asset_server: Res<AssetServer>) {
let proto = data.get_prototype("Happy").expect("Should exist!");
proto.spawn(&mut commands, &data, &asset_server);
let proto = data.get_prototype("Sad").expect("Should exist!");
proto.spawn(&mut commands, &data, &asset_server);
let proto = data.get_prototype("Silly").expect("Should exist!");
proto.spawn(&mut commands, &data, &asset_server);
let proto = data.get_prototype("Angry").expect("Should exist!");
proto.spawn(&mut commands, &data, &asset_server);
let proto = data.get_prototype("Happy").expect("Should exist!");
proto.spawn(&mut commands, &data, &asset_server);
let proto = data.get_prototype("Sad").expect("Should exist!");
proto.spawn(&mut commands, &data, &asset_server);
let proto = data.get_prototype("Silly").expect("Should exist!");
proto.spawn(&mut commands, &data, &asset_server);
let proto = data.get_prototype("Angry").expect("Should exist!");
proto.spawn(&mut commands, &data, &asset_server);
}

fn print_emojies(query: Query<&Emoji, Added<Emoji>>) {
for emoji in query.iter() {
println!("{}", emoji.0);
}
for emoji in query.iter() {
println!("{}", emoji.0);
}
}

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugin(ProtoPlugin::default())
.add_startup_system(spawn_emojis)
.add_system(print_emojies)
.run();
App::new()
.add_plugins(DefaultPlugins)
.add_plugin(ProtoPlugin::default())
.add_startup_system(spawn_emojis)
.add_system(print_emojies)
.run();
}
Loading

0 comments on commit 22c84e3

Please sign in to comment.