synkit_core/traits/
to_tokens.rs

1use super::printer::Printer;
2
3/// Trait for converting AST nodes back to text.
4///
5/// `ToTokens` is the inverse of `Parse` - it converts parsed structures
6/// back into their textual representation. This enables:
7///
8/// - Code formatting / pretty-printing
9/// - Source-to-source transformations
10/// - Round-trip testing (parse → modify → print)
11///
12/// # Associated Types
13///
14/// - [`Printer`]: The printer implementation for formatting output
15///
16/// # Required Methods
17///
18/// - `write(&self, printer)`: Write this value to the printer
19///
20/// # Provided Methods
21///
22/// - `to_string_formatted()`: Convenience method for getting a String
23///
24/// # Example
25///
26/// ```ignore
27/// use synkit::{ToTokens, Printer};
28///
29/// struct BinaryExpr {
30///     left: Box<Expr>,
31///     op: &'static str,
32///     right: Box<Expr>,
33/// }
34///
35/// impl ToTokens for BinaryExpr {
36///     type Printer = MyPrinter;
37///
38///     fn write(&self, p: &mut Self::Printer) {
39///         self.left.write(p);
40///         p.write(" ");
41///         p.write(self.op);
42///         p.write(" ");
43///         self.right.write(p);
44///     }
45/// }
46/// ```
47///
48/// # Blanket Implementations
49///
50/// - `Option<T>`: Writes nothing for `None`, delegates for `Some`
51/// - `Box<T>`: Delegates to inner value
52/// - `Vec<T>`: Writes each element in sequence
53/// - `&T`: Delegates to referenced value
54pub trait ToTokens {
55    /// The printer type for formatting output.
56    type Printer: Printer;
57
58    /// Write this value to the printer.
59    ///
60    /// # Arguments
61    ///
62    /// * `printer` - The printer to write to
63    fn write(&self, printer: &mut Self::Printer);
64
65    /// Convert to a formatted string.
66    ///
67    /// Convenience method that creates a default printer, writes to it,
68    /// and returns the result as a String.
69    ///
70    /// # Returns
71    ///
72    /// The formatted string representation
73    fn to_string_formatted(&self) -> String
74    where
75        Self::Printer: Default,
76    {
77        let mut printer = Self::Printer::default();
78        self.write(&mut printer);
79        printer.into_string()
80    }
81}
82
83impl<T: ToTokens> ToTokens for Option<T> {
84    type Printer = T::Printer;
85
86    fn write(&self, p: &mut Self::Printer) {
87        if let Some(v) = self {
88            v.write(p);
89        }
90    }
91}
92
93impl<T: ToTokens> ToTokens for Box<T> {
94    type Printer = T::Printer;
95
96    fn write(&self, p: &mut Self::Printer) {
97        self.as_ref().write(p);
98    }
99}
100
101impl<T: ToTokens> ToTokens for Vec<T> {
102    type Printer = T::Printer;
103
104    fn write(&self, p: &mut Self::Printer) {
105        for item in self {
106            item.write(p);
107        }
108    }
109}
110
111impl<T: ToTokens> ToTokens for &T {
112    type Printer = T::Printer;
113
114    fn write(&self, p: &mut Self::Printer) {
115        (*self).write(p);
116    }
117}