1#![allow(missing_debug_implementations)]
2#![unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
3
4use super::*;
7use crate::hint::unreachable_unchecked;
8use crate::ptr::NonNull;
9
10#[lang = "format_placeholder"]
11#[derive(Copy, Clone)]
12pub struct Placeholder {
13 pub position: usize,
14 pub fill: char,
15 pub align: Alignment,
16 pub flags: u32,
17 pub precision: Count,
18 pub width: Count,
19}
20
21impl Placeholder {
22 #[inline]
23 pub const fn new(
24 position: usize,
25 fill: char,
26 align: Alignment,
27 flags: u32,
28 precision: Count,
29 width: Count,
30 ) -> Self {
31 Self { position, fill, align, flags, precision, width }
32 }
33}
34
35#[lang = "format_alignment"]
36#[derive(Copy, Clone, PartialEq, Eq)]
37pub enum Alignment {
38 Left,
39 Right,
40 Center,
41 Unknown,
42}
43
44#[lang = "format_count"]
47#[derive(Copy, Clone)]
48pub enum Count {
49 #[cfg(bootstrap)]
51 Is(usize),
52 #[cfg(not(bootstrap))]
54 Is(u16),
55 Param(usize),
57 Implied,
59}
60
61#[derive(Copy, Clone)]
63pub(super) enum Flag {
64 SignPlus,
65 SignMinus,
66 Alternate,
67 SignAwareZeroPad,
68 DebugLowerHex,
69 DebugUpperHex,
70}
71
72#[derive(Copy, Clone)]
73enum ArgumentType<'a> {
74 Placeholder {
75 value: NonNull<()>,
78 formatter: unsafe fn(NonNull<()>, &mut Formatter<'_>) -> Result,
79 _lifetime: PhantomData<&'a ()>,
80 },
81 Count(u16),
82}
83
84#[lang = "format_argument"]
95#[derive(Copy, Clone)]
96pub struct Argument<'a> {
97 ty: ArgumentType<'a>,
98}
99
100#[rustc_diagnostic_item = "ArgumentMethods"]
101impl Argument<'_> {
102 #[inline]
103 const fn new<'a, T>(x: &'a T, f: fn(&T, &mut Formatter<'_>) -> Result) -> Argument<'a> {
104 Argument {
105 ty: ArgumentType::Placeholder {
108 value: NonNull::from_ref(x).cast(),
109 formatter: unsafe { mem::transmute(f) },
111 _lifetime: PhantomData,
112 },
113 }
114 }
115
116 #[inline]
117 pub fn new_display<T: Display>(x: &T) -> Argument<'_> {
118 Self::new(x, Display::fmt)
119 }
120 #[inline]
121 pub fn new_debug<T: Debug>(x: &T) -> Argument<'_> {
122 Self::new(x, Debug::fmt)
123 }
124 #[inline]
125 pub fn new_debug_noop<T: Debug>(x: &T) -> Argument<'_> {
126 Self::new(x, |_, _| Ok(()))
127 }
128 #[inline]
129 pub fn new_octal<T: Octal>(x: &T) -> Argument<'_> {
130 Self::new(x, Octal::fmt)
131 }
132 #[inline]
133 pub fn new_lower_hex<T: LowerHex>(x: &T) -> Argument<'_> {
134 Self::new(x, LowerHex::fmt)
135 }
136 #[inline]
137 pub fn new_upper_hex<T: UpperHex>(x: &T) -> Argument<'_> {
138 Self::new(x, UpperHex::fmt)
139 }
140 #[inline]
141 pub fn new_pointer<T: Pointer>(x: &T) -> Argument<'_> {
142 Self::new(x, Pointer::fmt)
143 }
144 #[inline]
145 pub fn new_binary<T: Binary>(x: &T) -> Argument<'_> {
146 Self::new(x, Binary::fmt)
147 }
148 #[inline]
149 pub fn new_lower_exp<T: LowerExp>(x: &T) -> Argument<'_> {
150 Self::new(x, LowerExp::fmt)
151 }
152 #[inline]
153 pub fn new_upper_exp<T: UpperExp>(x: &T) -> Argument<'_> {
154 Self::new(x, UpperExp::fmt)
155 }
156 #[inline]
157 #[track_caller]
158 pub const fn from_usize(x: &usize) -> Argument<'_> {
159 if *x > u16::MAX as usize {
160 panic!("Formatting argument out of range");
161 }
162 Argument { ty: ArgumentType::Count(*x as u16) }
163 }
164
165 #[allow(inline_no_sanitize)]
174 #[no_sanitize(cfi, kcfi)]
175 #[inline]
176 pub(super) unsafe fn fmt(&self, f: &mut Formatter<'_>) -> Result {
177 match self.ty {
178 ArgumentType::Placeholder { formatter, value, .. } => unsafe { formatter(value, f) },
186 ArgumentType::Count(_) => unsafe { unreachable_unchecked() },
188 }
189 }
190
191 #[inline]
192 pub(super) const fn as_u16(&self) -> Option<u16> {
193 match self.ty {
194 ArgumentType::Count(count) => Some(count),
195 ArgumentType::Placeholder { .. } => None,
196 }
197 }
198
199 #[inline]
210 pub const fn none() -> [Self; 0] {
211 []
212 }
213}
214
215#[lang = "format_unsafe_arg"]
219pub struct UnsafeArg {
220 _private: (),
221}
222
223impl UnsafeArg {
224 #[inline]
227 pub const unsafe fn new() -> Self {
228 Self { _private: () }
229 }
230}