1#![cfg_attr(not(feature = "std"), no_std)]
2
3extern crate alloc;
4
5#[macro_use]
6mod helpers;
7mod escape;
8
9use alloc::string::String;
10
11pub use escape::*;
12
13pub trait Render {
20 fn render_to(self, buf: &mut String);
21
22 #[inline]
23 fn render(self) -> String
24 where
25 Self: Sized,
26 {
27 let mut buf = String::new();
28 self.render_to(&mut buf);
29 buf
30 }
31}
32
33via_itoap! {
34 isize i8 i16 i32 i64 i128
35 usize u8 u16 u32 u64 u128
36}
37
38via_ryu! { f32 f64 }
39
40impl Render for &str {
41 #[inline]
42 fn render_to(self, buf: &mut String) {
43 escape_into(self, buf)
44 }
45}
46
47impl Render for String {
48 #[inline]
49 fn render_to(self, buf: &mut String) {
50 self.as_str().render_to(buf)
51 }
52}
53
54impl Render for &String {
55 #[inline]
56 fn render_to(self, buf: &mut String) {
57 self.as_str().render_to(buf)
58 }
59}
60
61impl Render for char {
62 #[inline]
63 fn render_to(self, buf: &mut String) {
64 escape_into(self.encode_utf8(&mut [0; 4]), buf);
65 }
66}
67
68impl Render for bool {
69 #[inline]
70 fn render_to(self, buf: &mut String) {
71 buf.push_str(if self { "true" } else { "false" })
72 }
73}
74
75impl<F: FnOnce(&mut String)> Render for F {
76 #[inline]
77 fn render_to(self, buf: &mut String) {
78 (self)(buf)
79 }
80}
81
82impl<T: Render> Render for Option<T> {
83 #[inline]
84 fn render_to(self, buf: &mut String) {
85 if let Some(x) = self {
86 x.render_to(buf)
87 }
88 }
89}
90
91impl<T: Render, const N: usize> Render for [T; N] {
92 #[inline]
93 fn render_to(self, buf: &mut String) {
94 for x in self {
95 x.render_to(buf)
96 }
97 }
98}
99
100impl<T, I: Iterator, F> Render for core::iter::Map<I, F>
101where
102 T: Render,
103 F: FnMut(I::Item) -> T,
104{
105 #[inline]
106 fn render_to(self, buf: &mut String) {
107 for x in self {
108 x.render_to(buf)
109 }
110 }
111}
112
113impl<T: Render> Render for alloc::vec::IntoIter<T> {
114 #[inline]
115 fn render_to(self, buf: &mut String) {
116 for x in self {
117 x.render_to(buf)
118 }
119 }
120}