1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright (C) 2024 Ethan Uppal. All rights reserved.
//
// This file is part of inform. inform is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version. inform is distributed in the hope that
// it will be useful, but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details. You should have received a
// copy of the GNU Lesser General Public License along with inform. If not, see
// <https://www.gnu.org/licenses/>.
//! <div align="center">
//! <img src="./assets/inform-logo.svg" width="250px">
//! <p><strong>indent formatting, everywhere</strong></p>
//! </div>
//!
//! 
//! 
//! 
//! 
//! [](https://github.com/rust-secure-code/safety-dance/)
//!
//! `inform` gives you
//!
//! - A `std::fmt::Formatter` drop-in replacement designed for formatting
//! structured data such as AST nodes.
//! - More generally, an API for formatting any type implementing
//! `std::io::Write` or `std::fmt::Write` with indentation.
//!
//! The format and I/O implementations are behind [Cargo features](https://doc.rust-lang.org/cargo/reference/features.html) `"fmt"` and `"io"` respectively, both of which are enabled by default.
//!
//! ## Contents
//!
//! - [Examples](#examples)
//! - [Projects using `inform`](#projects-using-inform)
//! - [Alternatives](#alternatives)
//! - [License](#license)
//!
//! <a name="examples"></a>
//!
//! ## Examples
//!
//! Here's how you can use `fmt::IndentFormatter`:
//!
//! ```rs
//! use std::fmt::{self, Write};
//! use inform::common::IndentWriterCommon, fmt::IndentFormatter;
//!
//! struct TestIndentFormatter;
//!
//! impl fmt::Display for TestIndentFormatter {
//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
//! let mut f = IndentFormatter::new(f, 2);
//! writeln!(f, "hello\ngoodbye")?;
//! f.increase_indent();
//! writeln!(f, "hello\ngoodbye")?;
//! f.decrease_indent();
//! writeln!(f, "hello\ngoodbye")
//! }
//! }
//!
//! #[test]
//! fn test_indent_formatter() {
//! assert_eq!(
//! "hello\ngoodbye\n hello\n goodbye\nhello\ngoodbye\n",
//! TestIndentFormatter.to_string()
//! );
//! }
//! ```
//!
//! Here's how you can use `fmt::IndentWriter`:
//!
//! ```rs
//! use std::fmt::{self, Write};
//! use inform::common::IndentWriterCommon, fmt::IndentWriter;
//!
//! fn write_text(str: &mut String) -> fmt::Result {
//! let mut f = IndentWriter::new(str, 2);
//! writeln!(f, "hello\ngoodbye")?;
//! f.increase_indent();
//! writeln!(f, "hello\ngoodbye")?;
//! f.decrease_indent();
//! writeln!(f, "hello\ngoodbye")
//! }
//!
//! #[test]
//! fn test_indent_writer() {
//! let mut buffer = String::new();
//! write_text(&mut buffer).expect("failed to format");
//! assert_eq!(
//! "hello\ngoodbye\n hello\n goodbye\nhello\ngoodbye\n",
//! buffer
//! );
//! }
//! ```
//!
//! <a name="projects-using-inform"></a>
//!
//! ## Projects using `inform`
//!
//! - [`calyx-writer`](https://github.com/calyxir/calyx/tree/main/tools/calyx-writer)
//! - [`spadefmt`](https://github.com/ethanuppal/spadefmt)
//! - [`pulsar`](https://github.com/ethanuppal/pulsar/tree/main)
//!
//! <a name="alternatives"></a>
//!
//! ## Alternatives
//!
//! The following crates are alternatives that I found did not fit my use case.
//!
//! - <https://crates.io/crates/indent>
//! - <https://crates.io/crates/indenter>
//! - <https://crates.io/crates/indentation>
//! - <https://docs.rs/indent_write/latest/indent_write/index.html>
//!
//! <a name="license"></a>
//!
//! ## License
//!
//! A copy of the LGPL License is provided in the [LICENSE](LICENSE) file.