mirror of
https://github.com/Noratrieb/mono-fmt.git
synced 2026-01-14 15:25:08 +01:00
core tests build
This commit is contained in:
parent
bfd86b1338
commit
010126ce0b
5 changed files with 147 additions and 18 deletions
|
|
@ -1,6 +1,6 @@
|
|||
use std::cell::Cell;
|
||||
|
||||
use proc_macro2::{Ident, Span, TokenStream};
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::{quote, ToTokens};
|
||||
|
||||
use crate::{
|
||||
|
|
@ -90,13 +90,14 @@ impl ToTokens for Scoped<'_, FormatArg<'_>> {
|
|||
.iter()
|
||||
.find(|(arg, _)| arg == name)
|
||||
.map(|(_, expr)| expr.to_token_stream())
|
||||
.unwrap_or_else(|| Ident::new(name, Span::call_site()).to_token_stream()),
|
||||
.unwrap_or_else(|| {
|
||||
Ident::new(name, self.input.format_str.span()).to_token_stream()
|
||||
}),
|
||||
};
|
||||
|
||||
let opt_ty = opt_ty_tokens(self.scope(&self.inner.format_spec.formatter_args));
|
||||
let opt_values = opt_value_tokens(self.scope(&self.inner.format_spec.formatter_args));
|
||||
|
||||
|
||||
tokens.extend(quote! { #prefix::#base::<_, #opt_ty>(#expr, #opt_values) })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
24
src/args.rs
24
src/args.rs
|
|
@ -27,18 +27,18 @@ macro_rules! tuple_args {
|
|||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
tuple_args!(
|
||||
A1 A2 A3 A4 A5 A6 A7 A8 A9 A10
|
||||
A11 A12 A13 A14 A15 A16 A17 A18 A19 A20
|
||||
A21 A22 A23 A24 A25 A26 A27 A28 A29 A30
|
||||
A31 A32 A33 A34 A35 A36 A37 A38 A39 A40
|
||||
// A41 A42 A43 A44 A45 A46 A47 A48 A49 A50
|
||||
// A51 A52 A53 A54 A55 A56 A57 A58 A59 A60
|
||||
// A61 A62 A63 A64 A65 A66 A67 A68 A69 A70
|
||||
// A71 A72 A73 A74 A75 A76 A77 A78 A79 A80
|
||||
// A81 A82 A83 A84 A85 A86 A87 A88 A89 A90
|
||||
// A91 A92 A93 A94 A95 A96 A97 A98 A99 A100
|
||||
);
|
||||
tuple_args!(
|
||||
A1 A2 A3 A4 A5 A6 A7 A8 A9 A10
|
||||
A11 A12 A13 A14 A15 A16 A17 A18 A19 A20
|
||||
A21 A22 A23 A24 A25 A26 A27 A28 A29 A30
|
||||
A31 A32 A33 A34 A35 A36 A37 A38 A39 A40
|
||||
// A41 A42 A43 A44 A45 A46 A47 A48 A49 A50
|
||||
// A51 A52 A53 A54 A55 A56 A57 A58 A59 A60
|
||||
// A61 A62 A63 A64 A65 A66 A67 A68 A69 A70
|
||||
// A71 A72 A73 A74 A75 A76 A77 A78 A79 A80
|
||||
// A81 A82 A83 A84 A85 A86 A87 A88 A89 A90
|
||||
// A91 A92 A93 A94 A95 A96 A97 A98 A99 A100
|
||||
);
|
||||
|
||||
pub struct Str(pub &'static str);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
//! A bunch of impls copied from all over the place
|
||||
|
||||
use crate::{Debug, FmtOpts, Formatter, Result, Write};
|
||||
use impl_prelude::*;
|
||||
|
||||
mod impl_prelude {
|
||||
pub use crate::*;
|
||||
}
|
||||
|
||||
impl<T: Debug + ?Sized> Debug for &T {
|
||||
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result {
|
||||
|
|
@ -19,3 +23,81 @@ impl<T: Debug> Debug for [T] {
|
|||
f.debug_list().entries(self.iter()).finish()
|
||||
}
|
||||
}
|
||||
|
||||
// pointers
|
||||
mod pointers {
|
||||
use super::impl_prelude::*;
|
||||
|
||||
impl<T: ?Sized> Pointer for *const T {
|
||||
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result {
|
||||
pointer_fmt_inner((*self as *const ()) as usize, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Pointer for *mut T {
|
||||
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result {
|
||||
pointer_fmt_inner((*self as *mut ()) as usize, f)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<T: ?Sized> Pointer for &T {
|
||||
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result {
|
||||
Pointer::fmt(&(*self as *const T), f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Pointer for &mut T {
|
||||
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result {
|
||||
Pointer::fmt(&(&**self as *const T), f)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn pointer_fmt_inner<W: Write, O: FmtOpts>(
|
||||
ptr_addr: usize,
|
||||
f: &mut Formatter<W, O>,
|
||||
) -> Result {
|
||||
// The alternate flag is already treated by LowerHex as being special-
|
||||
// it denotes whether to prefix with 0x. We use it to work out whether
|
||||
// or not to zero extend, and then unconditionally set it to get the
|
||||
// prefix.
|
||||
if f.alternate() {
|
||||
let mut f = f.wrap_with(&crate::opts::WithSignAwareZeroPad(()));
|
||||
|
||||
if f.width().is_none() {
|
||||
const WIDTH: usize = (usize::BITS / 4) as usize + 2;
|
||||
|
||||
let mut f = f.wrap_with(&crate::opts::WithWidth::<(), WIDTH>(()));
|
||||
|
||||
let mut f = f.wrap_with(&crate::opts::WithAlternate(()));
|
||||
let ret = LowerHex::fmt(&ptr_addr, &mut f);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
let mut f = f.wrap_with(&crate::opts::WithAlternate(()));
|
||||
let ret = LowerHex::fmt(&ptr_addr, &mut f);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
let mut f = f.wrap_with(&crate::opts::WithAlternate(()));
|
||||
let ret = LowerHex::fmt(&ptr_addr, &mut f);
|
||||
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
mod char {
|
||||
use super::impl_prelude::*;
|
||||
|
||||
impl Display for char {
|
||||
fn fmt<W: Write, O: FmtOpts>(&self, f: &mut Formatter<W, O>) -> Result {
|
||||
if f.width().is_none() && f.precision().is_none() {
|
||||
f.write_char(*self)
|
||||
} else {
|
||||
f.pad(self.encode_utf8(&mut [0; 4]))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -314,4 +314,52 @@ impl<W: Write, O: FmtOpts> Formatter<W, O> {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn pad(&mut self, s: &str) -> Result {
|
||||
// Make sure there's a fast path up front
|
||||
if self.width().is_none() && self.precision().is_none() {
|
||||
return self.buf.write_str(s);
|
||||
}
|
||||
// The `precision` field can be interpreted as a `max-width` for the
|
||||
// string being formatted.
|
||||
let s = if let Some(max) = self.precision() {
|
||||
// If our string is longer that the precision, then we must have
|
||||
// truncation. However other flags like `fill`, `width` and `align`
|
||||
// must act as always.
|
||||
if let Some((i, _)) = s.char_indices().nth(max) {
|
||||
// LLVM here can't prove that `..i` won't panic `&s[..i]`, but
|
||||
// we know that it can't panic. Use `get` + `unwrap_or` to avoid
|
||||
// `unsafe` and otherwise don't emit any panic-related code
|
||||
// here.
|
||||
s.get(..i).unwrap_or(s)
|
||||
} else {
|
||||
&s
|
||||
}
|
||||
} else {
|
||||
&s
|
||||
};
|
||||
// The `width` field is more of a `min-width` parameter at this point.
|
||||
match self.width() {
|
||||
// If we're under the maximum length, and there's no minimum length
|
||||
// requirements, then we can just emit the string
|
||||
None => self.buf.write_str(s),
|
||||
Some(width) => {
|
||||
let chars_count = s.chars().count();
|
||||
// If we're under the maximum width, check if we're over the minimum
|
||||
// width, if so it's as easy as just emitting the string.
|
||||
if chars_count >= width {
|
||||
self.buf.write_str(s)
|
||||
}
|
||||
// If we're under both the maximum and the minimum width, then fill
|
||||
// up the minimum width with the specified string + some alignment.
|
||||
else {
|
||||
let align = Alignment::Left;
|
||||
let post_padding =
|
||||
self.padding(width - chars_count, Alignment::Right, self.fill(), align)?;
|
||||
self.buf.write_str(s)?;
|
||||
post_padding.write(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
use mono_fmt::{FmtOpts, Write};
|
||||
|
||||
#[macro_use]
|
||||
extern crate mono_fmt;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue