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

docs: Add rustdoc blocks. #23

Merged
merged 6 commits into from
May 1, 2023
Merged
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
44 changes: 18 additions & 26 deletions crates/events/src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,60 +5,52 @@ use std::sync::Arc;
use tokio::sync::RwLock;

pub struct Emitter<E: Event> {
subscribers: RwLock<Vec<BoxedSubscriber<E>>>,
subscribers: Arc<RwLock<Vec<BoxedSubscriber<E>>>>,
}

#[allow(clippy::new_without_default)]
impl<E: Event + 'static> Emitter<E> {
/// Create a new event emitter.
pub fn new() -> Self {
Emitter {
subscribers: RwLock::new(Vec::new()),
subscribers: Arc::new(RwLock::new(Vec::new())),
}
}

/// Return a count of how many subscribers have been registered.
pub async fn len(&self) -> usize {
self.subscribers.read().await.len()
}

/// Register a subscriber to receive events.
pub async fn subscribe<L: Subscriber<E> + 'static>(&self, subscriber: L) -> &Self {
self.subscribers.write().await.push(Box::new(subscriber));
self
}

/// Register a subscriber function to receive events.
pub async fn on<L: SubscriberFunc<E> + 'static>(&self, callback: L) -> &Self {
self.subscribe(CallbackSubscriber::new(callback, false))
.await
}

// pub async fn on_many<I, L>(&self, callbacks: I) -> &Self
// where
// I: Iterator<Item = L>,
// L: SubscriberFunc<E> + 'static,
// {
// for callback in callbacks {
// self.on(callback).await;
// }

// self
// }

/// Register a subscriber function that will unregister itself after the first
/// event is received. This is useful for one-time event handlers.
pub async fn once<L: SubscriberFunc<E> + 'static>(&self, callback: L) -> &Self {
self.subscribe(CallbackSubscriber::new(callback, true))
.await
}

// pub async fn once_many<I, L>(&self, callbacks: I) -> &Self
// where
// I: Iterator<Item = L>,
// L: SubscriberFunc<E> + 'static,
// {
// for callback in callbacks {
// self.once(callback).await;
// }

// self
// }

/// Emit the provided event to all registered subscribers. Subscribers will be
/// called in the order they were registered.
///
/// If a subscriber returns [EventState::Stop], no further subscribers will be called.
/// If a subscriber returns [EventState::Return], no further subscribers will be called
/// and the provided value will be returned.
/// If a subscriber returns [EventState::Continue], the next subscriber will be called.
///
/// When complete, the provided event will be returned along with the value returned
/// by the subscriber that returned [EventState::Return], or [None] if not occurred.
pub async fn emit(&self, event: E) -> miette::Result<(E, Option<E::Value>)> {
let mut result = None;
let mut remove_indices = HashSet::new();
Expand Down
6 changes: 5 additions & 1 deletion crates/framework/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub struct App {
}

impl App {
/// Create a new application instance.
#[allow(clippy::new_without_default)]
pub fn new() -> App {
let mut app = App {
Expand All @@ -56,15 +57,18 @@ impl App {
app
}

/// Setup `miette` diagnostics by registering error and panic hooks.
pub fn setup_diagnostics() {
crate::diagnostics::setup_miette();
}

/// Setup `tracing` messages with default options.
#[cfg(feature = "tracing")]
pub fn setup_tracing() {
Self::setup_tracing_with_options(TracingOptions::default())
}

/// Setup `tracing` messages with custom options.
#[cfg(feature = "tracing")]
pub fn setup_tracing_with_options(options: TracingOptions) {
crate::tracing::setup_tracing(options);
Expand Down Expand Up @@ -249,7 +253,7 @@ impl App {
resources: Resources,
emitters: Emitters,
) -> AppResult {
let mut futures = vec![];
let mut futures = Vec::with_capacity(systems.len());
let semaphore = Arc::new(Semaphore::new(num_cpus::get()));

for system in systems {
Expand Down
10 changes: 10 additions & 0 deletions crates/framework/src/emitters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ pub use starbase_events::{Emitter, Event, EventResult, EventState, Subscriber, S
create_instance_manager!(EmitterManager, EmitterInstance);

impl EmitterManager {
/// Emit the provided event to all registered subscribers. Subscribers will be
/// called in the order they were registered.
///
/// If a subscriber returns [EventState::Stop], no further subscribers will be called.
/// If a subscriber returns [EventState::Return], no further subscribers will be called
/// and the provided value will be returned.
/// If a subscriber returns [EventState::Continue], the next subscriber will be called.
///
/// When complete, the provided event will be returned along with the value returned
/// by the subscriber that returned [EventState::Return], or [None] if not occurred.
pub async fn emit<E: Event + 'static>(
&self,
event: E,
Expand Down
6 changes: 6 additions & 0 deletions crates/framework/src/tracing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,17 @@ where
}

pub struct TracingOptions {
/// Minimum level of messages to display.
pub default_level: LevelFilter,
/// List of modules/prefixes to only log.
pub filter_modules: Vec<String>,
/// Whether to intercept messages from the global `log` crate.
pub intercept_log: bool,
/// Name of the logging environment variable.
pub log_env: String,
/// Absolute path to a file to write logs to.
pub log_file: Option<PathBuf>,
/// Name of the testing environment variable.
pub test_env: String,
}

Expand Down
32 changes: 28 additions & 4 deletions crates/styles/src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub enum Style {
}

impl Style {
/// Convert the style to a specific [Color].
pub fn color(&self) -> Color {
match self {
Style::Failure => Color::Red,
Expand All @@ -63,10 +64,13 @@ impl Style {
}
}

/// Create a new `owo_colors` [Style][OwoStyle] instance and apply the given color.
pub fn create_style(color: u8) -> OwoStyle {
OwoStyle::new().color(XtermColors::from(color))
}

/// Paint and wrap the string with the appropriate ANSI color escape code.
/// If colors are disabled, the string is returned as-is.
pub fn paint<T: AsRef<str>>(color: u8, value: T) -> String {
if no_color() {
value.as_ref().to_string()
Expand All @@ -75,6 +79,7 @@ pub fn paint<T: AsRef<str>>(color: u8, value: T) -> String {
}
}

/// Paint the string with the given style.
pub fn paint_style<T: AsRef<str>>(style: Style, value: T) -> String {
if matches!(style, Style::File | Style::Path | Style::Shell) {
paint(style.color() as u8, clean_path(value.as_ref()))
Expand All @@ -85,62 +90,76 @@ pub fn paint_style<T: AsRef<str>>(style: Style, value: T) -> String {

// States

/// Paint a failure state.
pub fn failure<T: AsRef<str>>(value: T) -> String {
paint_style(Style::Failure, value)
}

/// Paint an invalid state.
pub fn invalid<T: AsRef<str>>(value: T) -> String {
paint_style(Style::Invalid, value)
}

/// Paint a muted dark state.
pub fn muted<T: AsRef<str>>(value: T) -> String {
paint_style(Style::Muted, value)
}

/// Paint a muted light state.
pub fn muted_light<T: AsRef<str>>(value: T) -> String {
paint_style(Style::MutedLight, value)
}

/// Paint a success state.
pub fn success<T: AsRef<str>>(value: T) -> String {
paint_style(Style::Success, value)
}

// Types

/// Paint a partial file path or glob pattern.
pub fn file<T: AsRef<str>>(path: T) -> String {
paint_style(Style::File, path)
}

/// Paint a hash-like value.
pub fn hash<T: AsRef<str>>(value: T) -> String {
paint_style(Style::Hash, value)
}

/// Paint an identifier.
pub fn id<T: AsRef<str>>(value: T) -> String {
paint_style(Style::Id, value)
}

/// Paint a label, heading, or title.
pub fn label<T: AsRef<str>>(value: T) -> String {
paint_style(Style::Label, value)
}

/// Paint an absolute file path.
pub fn path<T: AsRef<Path>>(path: T) -> String {
paint_style(Style::Path, path.as_ref().to_str().unwrap_or("<unknown>"))
}

/// Paint a shell command or input string.
pub fn shell<T: AsRef<str>>(cmd: T) -> String {
paint_style(Style::Shell, cmd)
}

/// Paint a symbol, value, or number.
pub fn symbol<T: AsRef<str>>(value: T) -> String {
paint_style(Style::Symbol, value)
}

/// Paint a URL.
pub fn url<T: AsRef<str>>(url: T) -> String {
paint_style(Style::Url, url)
}

// Helpers

/// Clean a file system path by replacing the home directory with `~`.
pub fn clean_path<T: AsRef<str>>(path: T) -> String {
let path = path.as_ref();

Expand All @@ -151,7 +170,8 @@ pub fn clean_path<T: AsRef<str>>(path: T) -> String {
}
}

// Based on https://github.com/debug-js/debug/blob/master/src/common.js#L41
/// Dynamically apply a color to the log target/module/namespace based
/// on the characters in the string.
pub fn log_target<T: AsRef<str>>(value: T) -> String {
let value = value.as_ref();
let mut hash: u32 = 0;
Expand All @@ -172,14 +192,18 @@ pub fn log_target<T: AsRef<str>>(value: T) -> String {
paint(COLOR_LIST_UNSUPPORTED[index], value)
}

/// Return true if color has been disabled for the `stderr` stream.
pub fn no_color() -> bool {
env::var("NO_COLOR").is_ok() || supports_color::on(supports_color::Stream::Stderr).is_none()
}

// 1 = 8
// 2 = 256
// 3 = 16m
/// Return a color level support for the `stderr` stream. 0 = no support, 1 = basic support,
/// 2 = 256 colors, and 3 = 16 million colors.
pub fn supports_color() -> u8 {
if no_color() {
return 0;
}

if let Some(support) = supports_color::on(supports_color::Stream::Stderr) {
if support.has_16m {
return 3;
Expand Down
1 change: 1 addition & 0 deletions crates/styles/src/stylize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::path::PathBuf;
pub use crate::color::Style;

pub trait Stylize {
/// Wrap the current value in the given style (an ANSI color escape code).
fn style(&self, style: Style) -> String;
}

Expand Down
1 change: 1 addition & 0 deletions crates/styles/src/theme.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::color::{self, Color};
use miette::{GraphicalTheme, ThemeStyles};

/// Create a graphical theme for use in `miette`.
pub fn create_graphical_theme() -> GraphicalTheme {
let mut theme = GraphicalTheme::unicode();

Expand Down
Loading