diff --git a/bastion/examples/getting_started.rs b/bastion/examples/getting_started.rs index 38a65b78..aae8287c 100644 --- a/bastion/examples/getting_started.rs +++ b/bastion/examples/getting_started.rs @@ -1,8 +1,14 @@ use bastion::prelude::*; fn main() { - // Initializing the system (this is required)... - Bastion::init(); + /// Creating the system's configuration... + let config = Config::new() + .hide_backtraces(); + // ...and initializing the system with it (this is required)... + Bastion::init_with(config); + + // Note that `Bastion::init();` would work too and initialize + // the system with the default config. // Starting the system... Bastion::start(); diff --git a/bastion/src/bastion.rs b/bastion/src/bastion.rs index 1c000490..b6f66767 100644 --- a/bastion/src/bastion.rs +++ b/bastion/src/bastion.rs @@ -1,5 +1,6 @@ use crate::broadcast::{Broadcast, Parent}; use crate::children::{Children, ChildrenRef}; +use crate::config::Config; use crate::message::{BastionMessage, Message}; use crate::supervisor::{Supervisor, SupervisorRef}; use crate::system::{System, SYSTEM, SYSTEM_SENDER}; @@ -12,12 +13,18 @@ use std::thread; /// /// # Example /// -/// ``` +/// ```rust /// use bastion::prelude::*; /// /// fn main() { -/// // Initializing the system (this is required)... -/// Bastion::init(); +/// /// Creating the system's configuration... +/// let config = Config::new() +/// .hide_backtraces(); +/// // ...and initializing the system with it (this is required)... +/// Bastion::init_with(config); +/// +/// // Note that `Bastion::init();` would work too and initialize +/// // the system with the default config. /// /// // Starting the system... /// Bastion::start(); @@ -136,14 +143,16 @@ pub struct Bastion { } impl Bastion { - /// Initializes the system if it hasn't already been done. + /// Initializes the system if it hasn't already been done, using + /// the default [`Config`]. /// - /// **It is required that you call this method at least once - /// before using any of bastion's features.** + /// **It is required that you call `Bastion::init` or + /// [`Bastion::init_with`] at least once before using any of + /// bastion's features.** /// /// # Example /// - /// ``` + /// ```rust /// use bastion::prelude::*; /// /// fn main() { @@ -156,9 +165,50 @@ impl Bastion { /// # Bastion::block_until_stopped(); /// } /// ``` + /// + /// [`Config`]: struct.Config.html + /// [`Bastion::init_with`]: #method.init_with pub fn init() { - // NOTE: this hides all panic messages - //std::panic::set_hook(Box::new(|_| ())); + let config = Config::default(); + Bastion::init_with(config) + } + + /// Initializes the system if it hasn't already been done, using + /// the specified [`Config`]. + /// + /// **It is required that you call [`Bastion::init`] or + /// `Bastion::init_with` at least once before using any of + /// bastion's features.** + /// + /// # Arguments + /// + /// * `config` - The configuration used to initialize the system. + /// + /// # Example + /// + /// ```rust + /// use bastion::prelude::*; + /// + /// fn main() { + /// let config = Config::new() + /// .show_backtraces(); + /// + /// Bastion::init_with(config); + /// + /// // You can now use bastion... + /// # + /// # Bastion::start(); + /// # Bastion::stop(); + /// # Bastion::block_until_stopped(); + /// } + /// ``` + /// + /// [`Config`]: struct.Config.html + /// [`Bastion::init`]: #method.init + pub fn init_with(config: Config) { + if config.backtraces().is_hide() { + std::panic::set_hook(Box::new(|_| ())); + } // NOTE: this is just to make sure that SYSTEM_SENDER has been initialized by lazy_static SYSTEM_SENDER.is_closed(); @@ -179,7 +229,7 @@ impl Bastion { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -234,7 +284,7 @@ impl Bastion { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -290,7 +340,7 @@ impl Bastion { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -335,7 +385,7 @@ impl Bastion { /// /// # Example /// - /// ``` + /// ```rust /// use bastion::prelude::*; /// /// fn main() { @@ -363,7 +413,7 @@ impl Bastion { /// /// # Example /// - /// ``` + /// ```rust /// use bastion::prelude::*; /// /// fn main() { @@ -391,7 +441,7 @@ impl Bastion { /// /// # Example /// - /// ``` + /// ```rust /// use bastion::prelude::*; /// /// fn main() { @@ -425,7 +475,7 @@ impl Bastion { /// /// # Example /// - /// ``` + /// ```rust /// use bastion::prelude::*; /// /// fn main() { diff --git a/bastion/src/children.rs b/bastion/src/children.rs index e59e5e7d..bb2e0ddd 100644 --- a/bastion/src/children.rs +++ b/bastion/src/children.rs @@ -38,7 +38,7 @@ struct Exec(Pin> + Send>>); /// /// # Example /// -/// ``` +/// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -241,7 +241,7 @@ impl Children { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -288,7 +288,7 @@ impl Children { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -557,7 +557,7 @@ impl ChildrenRef { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -594,7 +594,7 @@ impl ChildrenRef { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -644,7 +644,7 @@ impl ChildrenRef { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -672,7 +672,7 @@ impl ChildrenRef { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -872,7 +872,7 @@ impl ChildRef { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { diff --git a/bastion/src/config.rs b/bastion/src/config.rs new file mode 100644 index 00000000..26ecb1ea --- /dev/null +++ b/bastion/src/config.rs @@ -0,0 +1,136 @@ +#[derive(Default, Debug, Clone)] +/// The configuration that should be used to initialize the +/// system using [`Bastion::init_with`]. +/// +/// The default behaviors are the following: +/// - All backtraces are shown (see [`Config::show_backtraces`]). +/// +/// # Example +/// +/// ```rust +/// use bastion::prelude::*; +/// +/// fn main() { +/// let config = Config::new() +/// .show_backtraces(); +/// +/// Bastion::init_with(config); +/// +/// // You can now use bastion... +/// # +/// # Bastion::start(); +/// # Bastion::stop(); +/// # Bastion::block_until_stopped(); +/// } +/// ``` +/// +/// [`Bastion::init_with`]: struct.Bastion.html#method.init_with +pub struct Config { + backtraces: Backtraces, +} + +#[derive(PartialEq, Eq, Debug, Clone)] +pub(crate) enum Backtraces { + /// Shows all backtraces, like an application without + /// Bastion would. + Show, + // TODO: Catch, + /// Hides all backtraces. + Hide, +} + +impl Config { + /// Creates a new configuration with the following default + /// behaviors: + /// - All backtraces are shown (see [`Config::show_backtraces`]). + /// + /// [`Config::show_backtraces`]: #method.show_backtraces + pub fn new() -> Self { + Config::default() + } + + /// Makes Bastion show all backtraces, like an application + /// without it would. This can be useful when trying to + /// debug children panicking. + /// + /// Note that this is the default behavior. + /// + /// # Example + /// + /// ```rust + /// use bastion::prelude::*; + /// + /// fn main() { + /// let config = Config::new() + /// .show_backtraces(); + /// + /// Bastion::init_with(config); + /// + /// // You can now use bastion and it will show you the + /// // backtraces of panics... + /// # + /// # Bastion::start(); + /// # Bastion::stop(); + /// # Bastion::block_until_stopped(); + /// } + /// ``` + pub fn show_backtraces(mut self) -> Self { + self.backtraces = Backtraces::show(); + self + } + + /// Makes Bastion hide all backtraces. + /// + /// Note that the default behavior is to show all backtraces + /// (see [`Config::show_backtraces`]). + /// + /// # Example + /// + /// ```rust + /// use bastion::prelude::*; + /// + /// fn main() { + /// let config = Config::new() + /// .hide_backtraces(); + /// + /// Bastion::init_with(config); + /// + /// // You can now use bastion and no panic backtraces + /// // will be shown... + /// # + /// # Bastion::start(); + /// # Bastion::stop(); + /// # Bastion::block_until_stopped(); + /// } + /// ``` + /// + /// [`Config::show_backtraces`]: #method.show_backtraces + pub fn hide_backtraces(mut self) -> Self { + self.backtraces = Backtraces::hide(); + self + } + + pub(crate) fn backtraces(&self) -> &Backtraces { + &self.backtraces + } +} + +impl Backtraces { + fn show() -> Self { + Backtraces::Show + } + + fn hide() -> Self { + Backtraces::Hide + } + + pub(crate) fn is_hide(&self) -> bool { + self == &Backtraces::Hide + } +} + +impl Default for Backtraces { + fn default() -> Self { + Backtraces::Show + } +} diff --git a/bastion/src/context.rs b/bastion/src/context.rs index 47800176..c2351a14 100644 --- a/bastion/src/context.rs +++ b/bastion/src/context.rs @@ -117,7 +117,7 @@ impl BastionContext { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -151,7 +151,7 @@ impl BastionContext { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -188,7 +188,7 @@ impl BastionContext { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -248,7 +248,7 @@ impl BastionContext { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -293,7 +293,7 @@ impl BastionContext { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { diff --git a/bastion/src/lib.rs b/bastion/src/lib.rs index 2a1ced77..a90ac7a2 100644 --- a/bastion/src/lib.rs +++ b/bastion/src/lib.rs @@ -53,10 +53,12 @@ pub use self::bastion::Bastion; pub use self::callbacks::Callbacks; +pub use self::config::Config; mod bastion; mod broadcast; mod callbacks; +mod config; mod system; pub mod children; @@ -70,6 +72,7 @@ pub mod prelude { pub use crate::bastion::Bastion; pub use crate::callbacks::Callbacks; pub use crate::children::{ChildRef, Children, ChildrenRef}; + pub use crate::config::Config; pub use crate::context::{BastionContext, BastionId}; pub use crate::message::{Answer, Message, Msg, Sender}; pub use crate::msg; diff --git a/bastion/src/message.rs b/bastion/src/message.rs index 1549aabf..805f12e8 100644 --- a/bastion/src/message.rs +++ b/bastion/src/message.rs @@ -42,7 +42,7 @@ pub struct Sender(oneshot::Sender); /// /// # Example /// -/// ``` +/// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -118,7 +118,7 @@ pub struct Answer(Receiver); /// /// # Example /// -/// ``` +/// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -450,7 +450,7 @@ impl Future for Answer { /// /// # Example /// -/// ``` +/// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { diff --git a/bastion/src/supervisor.rs b/bastion/src/supervisor.rs index 67be039b..6da3783b 100644 --- a/bastion/src/supervisor.rs +++ b/bastion/src/supervisor.rs @@ -32,7 +32,7 @@ use std::task::Poll; /// /// # Example /// -/// ``` +/// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -287,7 +287,7 @@ impl Supervisor { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -339,7 +339,7 @@ impl Supervisor { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -393,7 +393,7 @@ impl Supervisor { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -456,7 +456,7 @@ impl Supervisor { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() { @@ -535,7 +535,7 @@ impl Supervisor { /// /// # Example /// - /// ``` + /// ```rust /// # use bastion::prelude::*; /// # /// # fn main() {