Skip to main content

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;