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
134
135
136
137
138
139
140
141
142
143
//! String formatting without memory allocator
//! ==========================================
//!
//! In bare matal systems, there is often the task of converting numbers into text and formatting
//! them. The standard Rust functions like format!, write! etc. cannot be used in no_std
//! environments because they require a memory allocator. The arrform! macro uses the standard
//! library functions, but writes to a fixed length array which is alocated on the stack.
//!
//! This crate is usable in no_std environments. This is a replacement for the format! macro, based
//! on a fixed-size array allocated on the stack.
//!
//! # arrform!
//!
//! ``` rust
//! use arrform::{arrform, ArrForm};
//!
//! let af = arrform!(64, "write some stuff {}: {:.2}", "foo", 42.3456);
//! assert_eq!("write some stuff foo: 42.35", af.as_str());
//! ```
//!
//! ## ArrForm struct as an alternative
//!
//! The [ArrForm] struct provides more detailed error handling and supports multiple use of the
//! same buffer. However, it is much more cumbersome to use and generates more syntactic noise.
//!
//! # Overhead
//!
//! The convenient option to format can cost a lot of storage space. On a Cortex M4 992 bytes of
//! program code are needed additionally, if instead of a simple string a simple u32 number is
//! embedded with the help of the macro. It becomes even more expensive if f32 numbers are output
//! formatted (30,928 bytes additional). The program code used to determine these numbers can be
//! found in the example directory.
//!
//! # License
//!
//! Apache version 2.0 or Mit
//!
use ;
use MaybeUninit;
use format_args;
/// Generates formatted text in a buffer on the stack
///
/// Allows precise handling of errors. A buffer created once can be used several times. The
/// application requires more typing and contains some syntactic noise.
/// ```
/// use arrform::ArrForm;
///
/// let mut af = ArrForm::<64>::new();
/// match af.format(format_args!("write some stuff {}: {:.2}", "foo", 42.3456)) {
/// Ok(()) => {
/// assert_eq!("write some stuff foo: 42.35", af.as_str());
/// assert_eq!(b"write some stuff foo: 42.35", af.as_bytes());
/// },
/// Err(_) => {
/// panic!("An error occurred");
/// }
/// }
///
/// // Use the buffer a second time
/// af.format(
/// format_args!("same buffer, new {}, int {}, float {:.1}", "text", 123, 4.1234)
/// ).unwrap();
///
/// assert_eq!("same buffer, new text, int 123, float 4.1", af.as_str());
/// ```
/// A macro to format numers into text, based on a fixed-size array allocated on the stack
///
/// This macro first reserves a buffer on the stack. Then it uses the struct [ArrForm] to format
/// text and numbers. It returns an instance of ArrForm that allows easy access to the contained
/// text. The macro panics if the buffer is chosen too small.
///
/// ```
/// use arrform::{arrform, ArrForm};
///
/// let af = arrform!(64, "write some {}, int {}, float {:.3}", "stuff", 4711, 3.1415);
/// assert_eq!("write some stuff, int 4711, float 3.142", af.as_str());
/// ```