Skip to content
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

Feature/docs n clippy #47

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
10 changes: 5 additions & 5 deletions src/actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub trait Message: 'static + Send {

/// Describes how to handle messages of a specific type.
/// Implementing Handler is a general way to handle incoming messages.
/// The type T is a message which can be handled by the actor.
/// The type `T` is a message which can be handled by the actor.
#[async_trait::async_trait]
pub trait Handler<T: Message>: Actor
where
Expand All @@ -28,7 +28,7 @@ where
/// Describes how to handle messages of a specific type.
/// Implementing Handler is a general way to handle incoming streams.
/// The type T is a stream message which can be handled by the actor.
/// Stream messages do not need to implement the `Message` trait.
/// Stream messages do not need to implement the [`Message`] trait.
#[async_trait::async_trait]
#[allow(unused_variables)]
pub trait StreamHandler<T: 'static>: Actor {
Expand All @@ -47,13 +47,13 @@ pub trait StreamHandler<T: 'static>: Actor {
}

/// Actors are objects which encapsulate state and behavior.
/// Actors run within a specific execution context `Context<A>`.
/// Actors run within a specific execution context [`Context<A>`].
/// The context object is available only during execution.
/// Each actor has a separate execution context.
///
/// Roles communicate by exchanging messages.
/// The requester can wait for a response.
/// By `Addr` referring to the actors, the actors must provide an `Handle<T>` implementation for this message.
/// By [`Addr`] referring to the actors, the actors must provide an [`Handler<T>`] implementation for this message.
/// All messages are statically typed.
#[async_trait::async_trait]
#[allow(unused_variables)]
Expand All @@ -68,7 +68,7 @@ pub trait Actor: Sized + Send + 'static {

/// Construct and start a new actor, returning its address.
///
/// This is constructs a new actor using the `Default` trait, and invokes its `start` method.
/// This is constructs a new actor using the [`Default`] trait, and invokes its [`start`](`Actor::start`) method.
async fn start_default() -> Result<Addr<Self>>
where
Self: Default,
Expand Down
33 changes: 19 additions & 14 deletions src/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ pub(crate) enum ActorEvent<A> {

/// The address of an actor.
///
/// When all references to `Addr<A>` are dropped, the actor ends.
/// You can use `Clone` trait to create multiple copies of `Addr<A>`.
/// When all references to [`Addr<A>`] are dropped, the actor ends.
/// You can use the [`Clone`] trait to create multiple copies of [`Addr<A>`].
pub struct Addr<A> {
pub(crate) actor_id: ActorId,
pub(crate) tx: Arc<mpsc::UnboundedSender<ActorEvent<A>>>,
Expand All @@ -38,6 +38,7 @@ impl<A> Clone for Addr<A> {
}

impl<A> Addr<A> {
/// Turns an [`Addr<A>`] into a [`WeakAddr<A>`]
pub fn downgrade(&self) -> WeakAddr<A> {
WeakAddr {
actor_id: self.actor_id,
Expand Down Expand Up @@ -104,15 +105,15 @@ impl<A: Actor> Addr<A> {
Ok(())
}

/// Create a `Caller<T>` for a specific message type
/// Create a [`Caller<T>`] for a specific message type
pub fn caller<T: Message>(&self) -> Caller<T>
where
A: Handler<T>,
{
let weak_tx = Arc::downgrade(&self.tx);

Caller {
actor_id: self.actor_id.clone(),
actor_id: self.actor_id,
caller_fn: Mutex::new(Box::new(move |msg| {
let weak_tx_option = weak_tx.upgrade();
Box::pin(async move {
Expand All @@ -137,14 +138,14 @@ impl<A: Actor> Addr<A> {
}
}

/// Create a `Sender<T>` for a specific message type
/// Create a [`Sender<T>`] for a specific message type
pub fn sender<T: Message<Result = ()>>(&self) -> Sender<T>
where
A: Handler<T>,
{
let weak_tx = Arc::downgrade(&self.tx);
Sender {
actor_id: self.actor_id.clone(),
actor_id: self.actor_id,
sender_fn: Box::new(move |msg| match weak_tx.upgrade() {
Some(tx) => {
mpsc::UnboundedSender::clone(&tx).start_send(ActorEvent::Exec(Box::new(
Expand All @@ -171,6 +172,10 @@ impl<A: Actor> Addr<A> {
}
}

/// Weak version of [`Addr<A>`].
///
/// This address will not prolong the lifetime of the actor.
/// In order to use a [`WeakAddr<A>`] you need to "upgrade" it to a proper [`Addr<A>`].
pub struct WeakAddr<A> {
pub(crate) actor_id: ActorId,
pub(crate) tx: Weak<mpsc::UnboundedSender<ActorEvent<A>>>,
Expand All @@ -190,15 +195,15 @@ impl<A> Hash for WeakAddr<A> {
}

impl<A> WeakAddr<A> {
/// Attempts to turn a [`WeakAddr<A>`] into an [`Addr<A>`].
///
/// If the original [`Addr<A>`] has already been dropped this method will return [`None`]
pub fn upgrade(&self) -> Option<Addr<A>> {
match self.tx.upgrade() {
Some(tx) => Some(Addr {
actor_id: self.actor_id,
tx,
rx_exit: self.rx_exit.clone(),
}),
None => None,
}
self.tx.upgrade().map(|tx| Addr {
actor_id: self.actor_id,
tx,
rx_exit: self.rx_exit.clone(),
})
}
}

Expand Down
10 changes: 7 additions & 3 deletions src/caller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ pub(crate) type SenderFn<T> = Box<dyn Fn(T) -> Result<()> + 'static + Send>;

/// Caller of a specific message type
///
/// Like `Sender<T>, Caller has a weak reference to the recipient of the message type, and so will not prevent an actor from stopping if all Addr's have been dropped elsewhere.
/// Like [`Sender<T>`], `Caller` has a weak reference to the recipient of the message type,
/// and so will not prevent an actor from stopping if all [`Addr`](`crate::Addr`)'s have been dropped elsewhere.

pub struct Caller<T: Message> {
/// Id of the corresponding [`Actor<A>`](crate::Actor<A>)
pub actor_id: ActorId,
pub(crate) caller_fn: Mutex<CallerFn<T>>,
}
Expand All @@ -40,10 +42,12 @@ impl<T: Message<Result = ()>> Hash for Caller<T> {

/// Sender of a specific message type
///
/// Like `Caller<T>, Sender has a weak reference to the recipient of the message type, and so will not prevent an actor from stopping if all Addr's have been dropped elsewhere.
/// This allows it to be used in `send_later` `send_interval` actor functions, and not keep the actor alive indefinitely even after all references to it have been dropped (unless `ctx.stop()` is called from within)
/// Like [`Caller<T>`], Sender has a weak reference to the recipient of the message type,
/// and so will not prevent an actor from stopping if all [`Addr`](`crate::Addr`)'s have been dropped elsewhere.
/// This allows it to be used in the `send_later` and`send_interval` actor functions, /// and not keep the actor alive indefinitely even after all references to it have been dropped (unless `ctx.stop()` is called from within)

pub struct Sender<T: Message> {
/// Id of the corresponding [`Actor<A>`](crate::actor::Actor)
pub actor_id: ActorId,
pub(crate) sender_fn: SenderFn<T>,
}
Expand Down
1 change: 0 additions & 1 deletion src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ impl<A> Context<A> {
/// Ok(())
/// }
/// ```
/// ```
pub fn add_stream<S>(&mut self, mut stream: S)
where
S: Stream + Unpin + Send + 'static,
Expand Down
17 changes: 11 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
//! * [Async-std](https://github.com/async-rs/async-std)

#![allow(clippy::type_complexity)]
#![warn(clippy::doc_markdown)]

mod actor;
mod addr;
Expand All @@ -72,21 +73,25 @@ mod service;
mod supervisor;

#[cfg(all(feature = "anyhow", feature = "eyre"))]
compile_error!(r#"
compile_error!(
r#"
features `xactor/anyhow` and `xactor/eyre` are mutually exclusive.
If you are trying to disable anyhow set `default-features = false`.
"#);
"#
);

#[cfg(feature="anyhow")]
#[cfg(feature = "anyhow")]
pub use anyhow as error;

#[cfg(feature="eyre")]
#[cfg(feature = "eyre")]
pub use eyre as error;

/// Alias of error::Result
#[cfg_attr(feature = "eyre", doc = "Alias of [`eyre::Result`]")]
#[cfg_attr(not(feature = "eyre"), doc = "Alias of [`anyhow::Result`]")]
pub type Result<T> = error::Result<T>;

/// Alias of error::Error
#[cfg_attr(feature = "eyre", doc = "Alias of [`eyre::Error`]")]
#[cfg_attr(not(feature = "eyre"), doc = "Alias of [`anyhow::Error`]")]
pub type Error = error::Error;

pub type ActorId = u64;
Expand Down