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    Is(usize),
51    Param(usize),
53    Implied,
55}
56
57#[derive(Copy, Clone)]
59pub(super) enum Flag {
60    SignPlus,
61    SignMinus,
62    Alternate,
63    SignAwareZeroPad,
64    DebugLowerHex,
65    DebugUpperHex,
66}
67
68#[derive(Copy, Clone)]
69enum ArgumentType<'a> {
70    Placeholder {
71        value: NonNull<()>,
74        formatter: unsafe fn(NonNull<()>, &mut Formatter<'_>) -> Result,
75        _lifetime: PhantomData<&'a ()>,
76    },
77    Count(usize),
78}
79
80#[lang = "format_argument"]
91#[derive(Copy, Clone)]
92pub struct Argument<'a> {
93    ty: ArgumentType<'a>,
94}
95
96#[rustc_diagnostic_item = "ArgumentMethods"]
97impl Argument<'_> {
98    #[inline]
99    const fn new<'a, T>(x: &'a T, f: fn(&T, &mut Formatter<'_>) -> Result) -> Argument<'a> {
100        Argument {
101            ty: ArgumentType::Placeholder {
104                value: NonNull::from_ref(x).cast(),
105                formatter: unsafe { mem::transmute(f) },
107                _lifetime: PhantomData,
108            },
109        }
110    }
111
112    #[inline]
113    pub fn new_display<T: Display>(x: &T) -> Argument<'_> {
114        Self::new(x, Display::fmt)
115    }
116    #[inline]
117    pub fn new_debug<T: Debug>(x: &T) -> Argument<'_> {
118        Self::new(x, Debug::fmt)
119    }
120    #[inline]
121    pub fn new_debug_noop<T: Debug>(x: &T) -> Argument<'_> {
122        Self::new(x, |_, _| Ok(()))
123    }
124    #[inline]
125    pub fn new_octal<T: Octal>(x: &T) -> Argument<'_> {
126        Self::new(x, Octal::fmt)
127    }
128    #[inline]
129    pub fn new_lower_hex<T: LowerHex>(x: &T) -> Argument<'_> {
130        Self::new(x, LowerHex::fmt)
131    }
132    #[inline]
133    pub fn new_upper_hex<T: UpperHex>(x: &T) -> Argument<'_> {
134        Self::new(x, UpperHex::fmt)
135    }
136    #[inline]
137    pub fn new_pointer<T: Pointer>(x: &T) -> Argument<'_> {
138        Self::new(x, Pointer::fmt)
139    }
140    #[inline]
141    pub fn new_binary<T: Binary>(x: &T) -> Argument<'_> {
142        Self::new(x, Binary::fmt)
143    }
144    #[inline]
145    pub fn new_lower_exp<T: LowerExp>(x: &T) -> Argument<'_> {
146        Self::new(x, LowerExp::fmt)
147    }
148    #[inline]
149    pub fn new_upper_exp<T: UpperExp>(x: &T) -> Argument<'_> {
150        Self::new(x, UpperExp::fmt)
151    }
152    #[inline]
153    pub const fn from_usize(x: &usize) -> Argument<'_> {
154        Argument { ty: ArgumentType::Count(*x) }
155    }
156
157    #[allow(inline_no_sanitize)]
166    #[no_sanitize(cfi, kcfi)]
167    #[inline]
168    pub(super) unsafe fn fmt(&self, f: &mut Formatter<'_>) -> Result {
169        match self.ty {
170            ArgumentType::Placeholder { formatter, value, .. } => unsafe { formatter(value, f) },
178            ArgumentType::Count(_) => unsafe { unreachable_unchecked() },
180        }
181    }
182
183    #[inline]
184    pub(super) const fn as_usize(&self) -> Option<usize> {
185        match self.ty {
186            ArgumentType::Count(count) => Some(count),
187            ArgumentType::Placeholder { .. } => None,
188        }
189    }
190
191    #[inline]
202    pub const fn none() -> [Self; 0] {
203        []
204    }
205}
206
207#[lang = "format_unsafe_arg"]
211pub struct UnsafeArg {
212    _private: (),
213}
214
215impl UnsafeArg {
216    #[inline]
219    pub const unsafe fn new() -> Self {
220        Self { _private: () }
221    }
222}