pw_format/lib.rs
1// Copyright 2023 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14
15//! The `pw_format` crate is a parser used to implement proc macros that:
16//! * Understand format string argument types at compile time.
17//! * Syntax check format strings.
18//!
19//! `pw_format` is written against `std` and is not intended to be
20//! used in an embedded context. Some efficiency and memory is traded for a
21//! more expressive interface that exposes the format string's "syntax tree"
22//! to the API client.
23//!
24//! # Proc Macros
25//!
26//! The [`macros`] module provides infrastructure for implementing proc macros
27//! that take format strings as arguments.
28//!
29//! # Example
30//!
31//! ```
32//! use pw_format::{
33//! Alignment, Argument, ConversionSpec, Flag, FormatFragment, FormatString,
34//! Length, MinFieldWidth, Precision, Primitive, Style,
35//! };
36//!
37//! let format_string =
38//! FormatString::parse_printf("long double %+ 4.2Lf is %-03hd%%.").unwrap();
39//!
40//! assert_eq!(format_string, FormatString {
41//! fragments: vec![
42//! FormatFragment::Literal("long double ".to_string()),
43//! FormatFragment::Conversion(ConversionSpec {
44//! argument: Argument::None,
45//! fill: ' ',
46//! alignment: Alignment::None,
47//! flags: [Flag::ForceSign, Flag::SpaceSign].into_iter().collect(),
48//! min_field_width: MinFieldWidth::Fixed(4),
49//! precision: Precision::Fixed(2),
50//! length: Some(Length::LongDouble),
51//! primitive: Primitive::Float,
52//! style: Style::None,
53//! }),
54//! FormatFragment::Literal(" is ".to_string()),
55//! FormatFragment::Conversion(ConversionSpec {
56//! argument: Argument::None,
57//! fill: ' ',
58//! alignment: Alignment::Left,
59//! flags: [Flag::LeftJustify, Flag::LeadingZeros]
60//! .into_iter()
61//! .collect(),
62//! min_field_width: MinFieldWidth::Fixed(3),
63//! precision: Precision::None,
64//! length: Some(Length::Short),
65//! primitive: Primitive::Integer,
66//! style: Style::None,
67//! }),
68//! FormatFragment::Literal("%.".to_string()),
69//! ]
70//! });
71//! ```
72#![deny(missing_docs)]
73
74pub mod macros;
75
76mod core_fmt;
77mod format_string;
78mod parser_util;
79mod printf;
80
81pub use format_string::{
82 Alignment, Arg, Argument, ConversionSpec, Flag, FormatError, FormatFragment, FormatString,
83 FormatStyle, Length, MinFieldWidth, Precision, Primitive, Style,
84};
85
86#[cfg(test)]
87mod tests;