libcst_native/nodes/
whitespace.rs1#[cfg(feature = "py")]
7use libcst_derive::TryIntoPy;
8
9use super::{Codegen, CodegenState};
10
11#[derive(Debug, Eq, PartialEq, Default, Clone)]
12#[cfg_attr(feature = "py", derive(TryIntoPy))]
13pub struct SimpleWhitespace<'a>(pub &'a str);
14
15impl<'a> Codegen<'a> for SimpleWhitespace<'a> {
16 fn codegen(&self, state: &mut CodegenState<'a>) {
17 state.add_token(self.0);
18 }
19}
20
21#[derive(Debug, Eq, PartialEq, Clone)]
22#[cfg_attr(feature = "py", derive(TryIntoPy))]
23pub struct Comment<'a>(pub &'a str);
24
25impl<'a> Default for Comment<'a> {
26 fn default() -> Self {
27 Self("#")
28 }
29}
30
31impl<'a> Codegen<'a> for Comment<'a> {
32 fn codegen(&self, state: &mut CodegenState<'a>) {
33 state.add_token(self.0);
34 }
35}
36
37#[derive(Debug, Eq, PartialEq, Default, Clone)]
38#[cfg_attr(feature = "py", derive(TryIntoPy))]
39pub struct Newline<'a>(pub Option<&'a str>, pub Fakeness);
40
41#[derive(Debug, PartialEq, Eq, Clone)]
42pub enum Fakeness {
43 Fake,
44 Real,
45}
46
47impl Default for Fakeness {
48 fn default() -> Self {
49 Self::Real
50 }
51}
52
53impl<'a> Codegen<'a> for Newline<'a> {
54 fn codegen(&self, state: &mut CodegenState<'a>) {
55 if let Fakeness::Fake = self.1 {
56 return;
57 }
58 if let Some(value) = self.0 {
59 state.add_token(value);
60 } else {
61 state.add_token(state.default_newline);
62 }
63 }
64}
65
66#[derive(Debug, Eq, PartialEq, Default, Clone)]
67#[cfg_attr(feature = "py", derive(TryIntoPy))]
68pub struct TrailingWhitespace<'a> {
69 pub whitespace: SimpleWhitespace<'a>,
70 pub comment: Option<Comment<'a>>,
71 pub newline: Newline<'a>,
72}
73
74impl<'a> Codegen<'a> for TrailingWhitespace<'a> {
75 fn codegen(&self, state: &mut CodegenState<'a>) {
76 self.whitespace.codegen(state);
77 if let Some(comment) = &self.comment {
78 comment.codegen(state);
79 }
80 self.newline.codegen(state);
81 }
82}
83
84#[derive(Debug, Clone, PartialEq, Eq)]
85#[cfg_attr(feature = "py", derive(TryIntoPy))]
86pub struct EmptyLine<'a> {
87 pub indent: bool,
88 pub whitespace: SimpleWhitespace<'a>,
89 pub comment: Option<Comment<'a>>,
90 pub newline: Newline<'a>,
91}
92
93impl<'a> Codegen<'a> for EmptyLine<'a> {
94 fn codegen(&self, state: &mut CodegenState<'a>) {
95 if self.indent {
96 state.add_indent()
97 }
98 self.whitespace.codegen(state);
99 if let Some(comment) = &self.comment {
100 comment.codegen(state);
101 }
102 self.newline.codegen(state);
103 }
104}
105
106impl<'a> Default for EmptyLine<'a> {
107 fn default() -> Self {
108 Self {
109 indent: true,
110 whitespace: Default::default(),
111 comment: Default::default(),
112 newline: Default::default(),
113 }
114 }
115}
116
117impl<'a> EmptyLine<'a> {
118 pub fn new(
119 indent: bool,
120 whitespace: SimpleWhitespace<'a>,
121 comment: Option<Comment<'a>>,
122 newline: Newline<'a>,
123 ) -> Self {
124 Self {
125 indent,
126 whitespace,
127 comment,
128 newline,
129 }
130 }
131}
132
133#[derive(Debug, Eq, PartialEq, Default, Clone)]
134#[cfg_attr(feature = "py", derive(TryIntoPy))]
135pub struct ParenthesizedWhitespace<'a> {
136 pub first_line: TrailingWhitespace<'a>,
137 pub empty_lines: Vec<EmptyLine<'a>>,
138 pub indent: bool,
139 pub last_line: SimpleWhitespace<'a>,
140}
141
142impl<'a> Codegen<'a> for ParenthesizedWhitespace<'a> {
143 fn codegen(&self, state: &mut CodegenState<'a>) {
144 self.first_line.codegen(state);
145 for line in &self.empty_lines {
146 line.codegen(state);
147 }
148 if self.indent {
149 state.add_indent()
150 }
151 self.last_line.codegen(state);
152 }
153}
154
155#[derive(Debug, Eq, PartialEq, Clone)]
156#[cfg_attr(feature = "py", derive(TryIntoPy))]
157pub enum ParenthesizableWhitespace<'a> {
158 SimpleWhitespace(SimpleWhitespace<'a>),
159 ParenthesizedWhitespace(ParenthesizedWhitespace<'a>),
160}
161
162impl<'a> Codegen<'a> for ParenthesizableWhitespace<'a> {
163 fn codegen(&self, state: &mut CodegenState<'a>) {
164 match self {
165 Self::SimpleWhitespace(w) => w.codegen(state),
166 Self::ParenthesizedWhitespace(w) => w.codegen(state),
167 }
168 }
169}
170
171impl<'a> Default for ParenthesizableWhitespace<'a> {
172 fn default() -> Self {
173 Self::SimpleWhitespace(SimpleWhitespace(""))
174 }
175}