libcst_native/nodes/
codegen.rs1use std::fmt;
7#[derive(Debug)]
8pub struct CodegenState<'a> {
9 pub tokens: String,
10 pub indent_tokens: Vec<&'a str>,
11 pub default_newline: &'a str,
12 pub default_indent: &'a str,
13}
14
15impl<'a> CodegenState<'a> {
16 pub fn indent(&mut self, v: &'a str) {
17 self.indent_tokens.push(v);
18 }
19 pub fn dedent(&mut self) {
20 self.indent_tokens.pop();
21 }
22 pub fn add_indent(&mut self) {
23 self.tokens.extend(self.indent_tokens.iter().cloned());
24 }
25 pub fn add_token(&mut self, tok: &'a str) {
26 self.tokens.push_str(tok);
27 }
28}
29
30impl<'a> fmt::Display for CodegenState<'a> {
31 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32 write!(f, "{}", self.tokens)
33 }
34}
35
36pub trait Codegen<'a> {
37 fn codegen(&self, state: &mut CodegenState<'a>);
38}
39
40impl<'a, T> Codegen<'a> for Option<T>
41where
42 T: Codegen<'a>,
43{
44 fn codegen(&self, state: &mut CodegenState<'a>) {
45 if let Some(s) = &self {
46 s.codegen(state);
47 }
48 }
49}
50
51#[cfg(windows)]
52const LINE_ENDING: &str = "\r\n";
53#[cfg(not(windows))]
54const LINE_ENDING: &str = "\n";
55
56impl<'a> Default for CodegenState<'a> {
57 fn default() -> Self {
58 Self {
59 default_newline: LINE_ENDING,
60 default_indent: " ",
61 indent_tokens: Default::default(),
62 tokens: Default::default(),
63 }
64 }
65}