spannify/lib.rs
1//! # Spannify
2//!
3//! This crate provides functionality to produce nice-looking graphs that represent your
4//! callstack. It is designed to help developers trace and understand the execution flow of their
5//! programs, making it easier to debug and optimize their code.
6//!
7//! ## Overview
8//!
9//! The core functionality of this crate revolves around creating spans that represent different
10//! sections of your code. These spans are organized hierarchically, and the crate generates
11//! messages to visualize when you enter and exit each span. The generated messages can be
12//! customized to suit your preferences using a variety of configuration options.
13//!
14//! ## Modules
15//!
16//! - [`config`]: Contains the configuration structures and options for customizing the appearance
17//! and behavior of the callstack visualization.
18//! - [`core`]: Contains the core functionality for managing spans, generating messages, and
19//! handling the callstack visualization logic.
20//! - [`level`]: Contains the levels of spans, which determines if the span should be outputted or not
21//!
22//! ## Example
23//!
24//! ```rust
25//! use spannify::{config::Config, core::StdoutSpanner, spf};
26//! use std::sync::LazyLock;
27//!
28//! static SPANNER: LazyLock<StdoutSpanner> =
29//! LazyLock::new(|| StdoutSpanner::new().with_config(Config::new().with_skip(1)));
30//!
31//! fn fib(n: usize) -> usize {
32//! let _span = spf!(SPANNER, "fib({n})");
33//! match n {
34//! 0 => 0,
35//! 1 | 2 => 1,
36//! _ => fib(n - 1) + fib(n - 2),
37//! }
38//! }
39//!
40//! fn main() {
41//! fib(5);
42//! }
43//!
44//! ```
45//! ### Output
46//!
47//! ```text
48//!┌fib(5)
49//!| fib(4)
50//!| ┌fib(3)
51//!| ┆ fib(2)
52//!| ┆ fib(2)
53//!| ┆ fib(1)
54//!| ┆ fib(1)
55//!| └fib(3)
56//!| ┌fib(2)
57//!| └fib(2)
58//!| fib(4)
59//!| fib(3)
60//!| ┌fib(2)
61//!| └fib(2)
62//!| ┌fib(1)
63//!| └fib(1)
64//!| fib(3)
65//!└fib(5)
66//! ```
67//!
68//! ## Usage
69//!
70//! To use this crate, you typically start by creating a `spannify` instance with a desired writer
71//! and configuration. Then, you create spans by calling the `Span::enter` method, which tracks the
72//! entry and exit points of different sections of your code.
73//!
74//! ```rust
75//! use spannify::{config::Config, core::{StdoutSpanner}};
76//! use std::io::stdout;
77//!
78//! // Create a configuration
79//! let config = Config::default();
80//!
81//! // Create a spannify
82//! let spanner = StdoutSpanner::new().with_config(config);
83//!
84//! // Create a span
85//! {
86//! let _span = spanner.enter_span("main");
87//! // Your code here...
88//! }
89//! // The span is automatically dropped here, and the exit message is generated
90//! ```
91//!
92//! ## Configuration
93//!
94//! The [`config`] module provides various options to customize the appearance and behavior of the
95//! callstack visualization. This includes settings for indentation, depth display, and message
96//! formatting. You can create a custom configuration by modifying the default values.
97//!
98//! ```rust
99//! use spannify::config::Config;
100//!
101//! let mut config = Config::default();
102//! config.tabwidth = 4;
103//! config.skip = 2;
104//! config.depthmap = |depth| if depth % 2 == 0 { '|' } else { '^' };
105//!
106//! // Use this configuration when creating a spannify
107//! ```
108//!
109//! ## License
110//!
111//! This crate is licensed under the MIT License. See the LICENSE file for more details.
112//!
113//! ## Contributing
114//!
115//! Contributions are welcome! Please open an issue or submit a pull request
116
117#![doc(html_root_url = "https://docs.rs/spannify/latest")]
118#![deny(unsafe_code)]
119#![warn(
120 clippy::cognitive_complexity,
121 clippy::dbg_macro,
122 clippy::debug_assert_with_mut_call,
123 clippy::doc_link_with_quotes,
124 clippy::doc_markdown,
125 clippy::empty_line_after_outer_attr,
126 clippy::empty_structs_with_brackets,
127 clippy::float_cmp,
128 clippy::float_cmp_const,
129 clippy::float_equality_without_abs,
130 keyword_idents,
131 clippy::missing_const_for_fn,
132 missing_copy_implementations,
133 missing_debug_implementations,
134 clippy::missing_errors_doc,
135 clippy::missing_panics_doc,
136 clippy::mod_module_files,
137 non_ascii_idents,
138 noop_method_call,
139 clippy::option_if_let_else,
140 clippy::print_stderr,
141 clippy::print_stdout,
142 clippy::semicolon_if_nothing_returned,
143 clippy::unseparated_literal_suffix,
144 clippy::similar_names,
145 clippy::suspicious_operation_groupings,
146 unused_crate_dependencies,
147 unused_extern_crates,
148 unused_import_braces,
149 clippy::unused_self,
150 clippy::use_debug,
151 clippy::used_underscore_binding,
152 clippy::useless_let_if_seq,
153 clippy::wildcard_dependencies,
154 clippy::wildcard_imports
155)]
156
157pub mod config;
158pub mod core;
159pub mod level;