libcst_native/nodes/
codegen.rs

1// Copyright (c) Meta Platforms, Inc. and affiliates.
2//
3// This source code is licensed under the MIT license found in the
4// LICENSE file in the root directory of this source tree.
5
6use 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}