use ambassador::{delegate_to_remote_methods, delegatable_trait};
#[delegatable_trait]
pub trait Shout {
fn shout(&self, input: &str) -> String;
}
pub struct Cat;
impl Shout for Cat {
fn shout(&self, input: &str) -> String {
format!("{} - meow!", input)
}
}
pub struct BoxedCat(Box<Cat>);
impl BoxedCat {
fn inner(&self) -> &Cat { &self.0 }
}
#[delegate_to_remote_methods]
#[delegate(Shout, target_ref = "inner")]
impl BoxedCat {
// `inner` can be defined anywhere: trait method or inherent method, in this crate or elsewhere
fn inner(&self) -> &Cat;
}
It's identical to delegate_to_methods except:
it does not preserve the impl block it is applied to in its output
it checks that there are no method bodies or unused items in the impl block it is applied to
This allows it to be used in scenarios involving foreign Self types (without needing to create intermediary local traits to house the target methods) like the one described in #36:
tests and updates to the docs clarifying that #[delegate_to_methods] impl Trait for Type { ... } is permitted
some miscellaneous fixes and tests for the delegate(...) attr parsing logic
I can split these into their own PRs if required.
Open Questions
Is the name okay? delegate_to_remote_methods mirrors delegate_remote (which makes sense since, like delegate_remote does not require the type the impls are on to be local, this macro relaxes the requirement that the methods used to do the delegation be local) but it's perhaps misleading since delegate_to_remote_methods will also accept a remote type (as will delegate_to_methods if you place it on a block that implements a trait).
Currently the macro is pretty aggressive about checking that there aren't extra/unused items in the impl it is applied to; my thinking was that silently dropping these items could be a source of confusion. Do we want to relax these checks?
delegate_to_remote_methods
This PR adds
delegate_to_remote_methods
:It's identical to
delegate_to_methods
except:impl
block it is applied to in its outputThis allows it to be used in scenarios involving foreign
Self
types (without needing to create intermediary local traits to house the target methods) like the one described in #36:Other Stuff
There are a couple of other things in this PR:
#[delegate_to_methods] impl Trait for Type { ... }
is permitteddelegate(...)
attr parsing logicI can split these into their own PRs if required.
Open Questions
Is the name okay?
delegate_to_remote_methods
mirrorsdelegate_remote
(which makes sense since, likedelegate_remote
does not require the type the impls are on to be local, this macro relaxes the requirement that the methods used to do the delegation be local) but it's perhaps misleading sincedelegate_to_remote_methods
will also accept a remote type (as willdelegate_to_methods
if you place it on a block that implements a trait).Currently the macro is pretty aggressive about checking that there aren't extra/unused items in the
impl
it is applied to; my thinking was that silently dropping these items could be a source of confusion. Do we want to relax these checks?