graphql_toolkit_writer/fmt/
formatter.rs

1use std::io;
2
3/// A trait for writing GraphQL documents.
4pub trait Formatter {
5    /// Writes a raw GraphQL fragment that doesn't need escaping to the writer.
6    #[inline]
7    fn write_raw<W>(&mut self, writer: &mut W, fragment: &str) -> io::Result<()>
8    where
9        W: ?Sized + io::Write,
10    {
11        writer.write_all(fragment.as_bytes())
12    }
13
14    #[inline]
15    fn write_keyword<W>(&mut self, writer: &mut W, name: &str) -> io::Result<()>
16    where
17        W: ?Sized + io::Write,
18    {
19        writer.write_all(name.as_bytes())
20    }
21
22    /// Writes a whitespace separator to the specified writer.
23    ///
24    /// This is used to separate different parts of the GraphQL query,
25    /// For example:
26    ///
27    /// - To separate the operation type keyword from the name:
28    ///
29    ///   ```none
30    ///   query MyQuery { ... }
31    ///        ^
32    ///        |
33    ///        This is a separator
34    ///   ```
35    ///
36    /// - Or to separate the fragment name from the fragment definition,   or the fragment type
37    ///   condition keyword from the type name.
38    ///
39    ///   ```none
40    ///   fragment MyFragment on MyType { ... }
41    ///           ^             ^
42    ///           |             |
43    ///           |             This is a separator
44    ///           This is a separator
45    ///   ```
46    #[inline]
47    fn write_separator<W>(&mut self, writer: &mut W) -> io::Result<()>
48    where
49        W: ?Sized + io::Write,
50    {
51        writer.write_all(b" ")
52    }
53
54    #[inline]
55    fn before_operation_or_fragment_definition<W>(&mut self, _writer: &mut W) -> io::Result<()>
56    where
57        W: ?Sized + io::Write,
58    {
59        Ok(())
60    }
61
62    #[inline]
63    fn before_operation_variable_definitions<W>(&mut self, _writer: &mut W) -> io::Result<()>
64    where
65        W: ?Sized + io::Write,
66    {
67        Ok(())
68    }
69
70    /// Called after writing the operation name and/or arguments.
71    #[inline]
72    fn after_operation_or_fragment_signature<W>(&mut self, _writer: &mut W) -> io::Result<()>
73    where
74        W: ?Sized + io::Write,
75    {
76        Ok(())
77    }
78
79    #[inline]
80    fn after_selection_signature<W>(&mut self, _writer: &mut W) -> io::Result<()>
81    where
82        W: ?Sized + io::Write,
83    {
84        Ok(())
85    }
86
87    #[inline]
88    fn before_type_condition<W>(&mut self, _writer: &mut W) -> io::Result<()>
89    where
90        W: ?Sized + io::Write,
91    {
92        Ok(())
93    }
94
95    #[inline]
96    fn before_directive<W>(&mut self, _writer: &mut W) -> io::Result<()>
97    where
98        W: ?Sized + io::Write,
99    {
100        Ok(())
101    }
102
103    /// Writes a string fragment that doesn't need any escaping to the specified writer.
104    // TODO: Add an escaped variant, and rename to string_unescaped
105    #[inline]
106    fn write_string_fragment<W>(&mut self, writer: &mut W, fragment: &str) -> io::Result<()>
107    where
108        W: ?Sized + io::Write,
109    {
110        writer.write_all(fragment.as_bytes())
111    }
112
113    /// Writes a `$` to the specified writer.
114    ///
115    /// This must be called before writing a variable name.
116    #[inline]
117    fn begin_variable<W>(&mut self, writer: &mut W) -> io::Result<()>
118    where
119        W: ?Sized + io::Write,
120    {
121        writer.write_all(b"$")
122    }
123
124    /// Writes a `!` to the specified writer.
125    ///
126    /// This must be called after writing a variable type name.
127    #[inline]
128    fn write_non_null_type_indicator<W>(&mut self, writer: &mut W) -> io::Result<()>
129    where
130        W: ?Sized + io::Write,
131    {
132        writer.write_all(b"!")
133    }
134
135    /// Writes a `@` to the specified writer.
136    ///
137    /// This must be called before writing a directive name.
138    #[inline]
139    fn begin_directive<W>(&mut self, writer: &mut W) -> io::Result<()>
140    where
141        W: ?Sized + io::Write,
142    {
143        writer.write_all(b"@")
144    }
145
146    /// Writes a `:` to the specified writer.
147    fn write_name_value_separator<W>(&mut self, writer: &mut W) -> io::Result<()>
148    where
149        W: ?Sized + io::Write,
150    {
151        writer.write_all(b":")
152    }
153
154    /// Writes a `=` to the specified writer.
155    ///
156    /// This is used to separate the name of a variable from its default value.
157    fn write_variable_default_value_separator<W>(&mut self, writer: &mut W) -> io::Result<()>
158    where
159        W: ?Sized + io::Write,
160    {
161        writer.write_all(b"=")
162    }
163
164    /// Writes a `,` to the specified writer.
165    ///
166    /// For example, this is used to separate items in a list (arguments,
167    /// variable definitions, etc.), or to separate key-value pairs in an
168    /// object value.
169    ///
170    /// ```none
171    /// query MyQuery($var1: String, $var2: Int) { ... }
172    ///                            ^
173    ///                            |
174    ///                          This is an item separator
175    /// ```
176    ///
177    /// ```none
178    /// query MyQuery { field1(arg1: [1, 2, 3]) { ... } }
179    ///                                ^  ^
180    ///                                |  |
181    ///                                |  This is an item separator
182    ///                               This is an item separator
183    /// ```
184    fn write_item_separator<W>(&mut self, writer: &mut W) -> io::Result<()>
185    where
186        W: ?Sized + io::Write,
187    {
188        writer.write_all(b",")
189    }
190
191    /// Writes a `(` to the specified writer.
192    #[inline]
193    fn begin_parentheses<W>(&mut self, writer: &mut W) -> io::Result<()>
194    where
195        W: ?Sized + io::Write,
196    {
197        writer.write_all(b"(")
198    }
199
200    /// Writes a `)` to the specified writer.
201    #[inline]
202    fn end_parentheses<W>(&mut self, writer: &mut W) -> io::Result<()>
203    where
204        W: ?Sized + io::Write,
205    {
206        writer.write_all(b")")
207    }
208
209    /// Writes a `{` to the specified writer.
210    #[inline]
211    fn begin_block<W>(&mut self, writer: &mut W) -> io::Result<()>
212    where
213        W: ?Sized + io::Write,
214    {
215        writer.write_all(b"{")
216    }
217
218    /// Writes a `}` to the specified writer.
219    #[inline]
220    fn end_block<W>(&mut self, writer: &mut W) -> io::Result<()>
221    where
222        W: ?Sized + io::Write,
223    {
224        writer.write_all(b"}")
225    }
226
227    #[inline]
228    fn before_block_item<W>(&mut self, _writer: &mut W) -> io::Result<()>
229    where
230        W: ?Sized + io::Write,
231    {
232        Ok(())
233    }
234
235    #[inline]
236    fn after_block_item<W>(&mut self, writer: &mut W) -> io::Result<()>
237    where
238        W: ?Sized + io::Write,
239    {
240        writer.write_all(b",")
241    }
242
243    #[inline]
244    fn begin_string<W>(&mut self, writer: &mut W) -> io::Result<()>
245    where
246        W: ?Sized + io::Write,
247    {
248        writer.write_all(b"\"")
249    }
250
251    #[inline]
252    fn end_string<W>(&mut self, writer: &mut W) -> io::Result<()>
253    where
254        W: ?Sized + io::Write,
255    {
256        writer.write_all(b"\"")
257    }
258
259    /// Writes a `[` to the specified writer.
260    #[inline]
261    fn begin_array<W>(&mut self, writer: &mut W) -> io::Result<()>
262    where
263        W: ?Sized + io::Write,
264    {
265        writer.write_all(b"[")
266    }
267
268    /// Writes a `]` to the specified writer.
269    #[inline]
270    fn end_array<W>(&mut self, writer: &mut W) -> io::Result<()>
271    where
272        W: ?Sized + io::Write,
273    {
274        writer.write_all(b"]")
275    }
276
277    /// Writes the representation of a byte array. Formatters can choose whether
278    /// to represent bytes as a JSON array of integers (the default), or some
279    /// JSON string encoding like hex or base64.
280    #[inline]
281    fn write_byte_array<W>(&mut self, writer: &mut W, value: &[u8]) -> io::Result<()>
282    where
283        W: ?Sized + io::Write,
284    {
285        self.begin_array(writer)?;
286
287        let mut bytes = value.iter().peekable();
288        while let Some(byte) = bytes.next() {
289            self.write_u8(writer, *byte)?;
290
291            if bytes.peek().is_some() {
292                writer.write_all(b",")?;
293            }
294        }
295
296        self.end_array(writer)?;
297
298        Ok(())
299    }
300
301    /// Writes a `{` to the specified writer.
302    #[inline]
303    fn begin_object<W>(&mut self, writer: &mut W) -> io::Result<()>
304    where
305        W: ?Sized + io::Write,
306    {
307        writer.write_all(b"{")
308    }
309
310    /// Writes a `}` to the specified writer.
311    #[inline]
312    fn end_object<W>(&mut self, writer: &mut W) -> io::Result<()>
313    where
314        W: ?Sized + io::Write,
315    {
316        writer.write_all(b"}")
317    }
318
319    /// Writes a `null` value to the specified writer.
320    #[inline]
321    fn write_null<W>(&mut self, writer: &mut W) -> io::Result<()>
322    where
323        W: ?Sized + io::Write,
324    {
325        writer.write_all(b"null")
326    }
327
328    /// Writes a `true` or `false` value to the specified writer.
329    #[inline]
330    fn write_bool<W>(&mut self, writer: &mut W, value: bool) -> io::Result<()>
331    where
332        W: ?Sized + io::Write,
333    {
334        writer.write_all(if value { b"true" } else { b"false" })
335    }
336
337    /// Writes an unsigned byte value like "255" to the specified writer.
338    #[inline]
339    fn write_u8<W>(&mut self, writer: &mut W, value: u8) -> io::Result<()>
340    where
341        W: ?Sized + io::Write,
342    {
343        let mut buffer = itoa::Buffer::new();
344        let s = buffer.format(value);
345        writer.write_all(s.as_bytes())
346    }
347
348    /// Writes an integer value like `123` to the specified writer.
349    #[inline]
350    fn write_u64<W>(&mut self, writer: &mut W, value: u64) -> io::Result<()>
351    where
352        W: ?Sized + io::Write,
353    {
354        let mut buffer = itoa::Buffer::new();
355        let s = buffer.format(value);
356        writer.write_all(s.as_bytes())
357    }
358
359    /// Writes an integer value like `-123` to the specified writer.
360    #[inline]
361    fn write_i64<W>(&mut self, writer: &mut W, value: i64) -> io::Result<()>
362    where
363        W: ?Sized + io::Write,
364    {
365        let mut buffer = itoa::Buffer::new();
366        let s = buffer.format(value);
367        writer.write_all(s.as_bytes())
368    }
369
370    /// Writes a floating point value like `-31.26e+12` to the specified writer.
371    #[inline]
372    fn write_f64<W>(&mut self, writer: &mut W, value: f64) -> io::Result<()>
373    where
374        W: ?Sized + io::Write,
375    {
376        let mut buffer = ryu::Buffer::new();
377        let s = buffer.format_finite(value);
378        writer.write_all(s.as_bytes())
379    }
380}