1use std::fmt::{Display, Formatter};
11use std::io;
12
13use crate::{
14 CellStream, NativeParseError, ParseError, SourceFile, SourceId, Span, Spanned, ToCells,
15 ToTokens, TokenStream, parse_file, parse_native,
16 pretty::{PrettyOptions, PrettyReport, PrettyTree, format_cells, format_tree, print_report},
17};
18
19#[derive(Debug)]
31pub struct ParsedFile {
32 original_source: String,
33 source_id: SourceId,
34 cst: SourceFile,
35}
36
37impl ParsedFile {
38 pub fn from_source(source: impl Into<String>) -> Result<Self, ParseError> {
40 Self::from_source_with_id(source, SourceId::fresh())
41 }
42
43 pub fn from_source_with_id(
45 source: impl Into<String>,
46 source_id: SourceId,
47 ) -> Result<Self, ParseError> {
48 let original_source = source.into();
49 let cst = parse_file(&original_source, source_id)?;
50 Ok(Self {
51 original_source,
52 source_id,
53 cst,
54 })
55 }
56
57 pub fn from_source_native(source: impl Into<String>) -> Result<Self, NativeParseError> {
59 Self::from_source_native_with_id(source, SourceId::fresh())
60 }
61
62 pub fn from_source_native_with_id(
64 source: impl Into<String>,
65 source_id: SourceId,
66 ) -> Result<Self, NativeParseError> {
67 let original_source = source.into();
68 let cst = parse_native(&original_source, source_id)?;
69 Ok(Self {
70 original_source,
71 source_id,
72 cst,
73 })
74 }
75
76 pub fn original_source(&self) -> &str {
78 &self.original_source
79 }
80
81 pub fn source_id(&self) -> SourceId {
83 self.source_id
84 }
85
86 pub fn cst(&self) -> &SourceFile {
88 &self.cst
89 }
90
91 pub fn cst_mut(&mut self) -> &mut SourceFile {
93 &mut self.cst
94 }
95
96 pub fn edit(mut self, edit: impl FnOnce(&mut SourceFile)) -> Self {
98 edit(&mut self.cst);
99 self
100 }
101
102 pub fn into_cst(self) -> SourceFile {
104 self.cst
105 }
106
107 pub fn token_stream(&self) -> TokenStream {
109 self.cst.to_token_stream()
110 }
111
112 pub fn cell_stream(&self) -> CellStream {
114 self.cst.to_cell_stream(self.source_id)
115 }
116
117 pub fn to_source(&self) -> String {
119 self.token_stream().to_string()
120 }
121
122 pub fn pretty_tokens(&self) -> String {
125 format_cells(&self.cell_stream(), PrettyOptions::PLAIN)
126 }
127
128 pub fn pretty_cst(&self) -> String {
130 format_tree(&self.cst.pretty_tree(), PrettyOptions::PLAIN)
131 }
132
133 pub fn pretty_report(&self) -> PrettyReport<'_> {
135 PrettyReport::new(
136 &self.original_source,
137 self.cell_stream(),
138 self.cst.pretty_tree(),
139 )
140 }
141
142 pub fn print_pretty(&self) -> io::Result<()> {
145 print_report(self.pretty_report())
146 }
147}
148
149impl AsRef<SourceFile> for ParsedFile {
150 fn as_ref(&self) -> &SourceFile {
151 self.cst()
152 }
153}
154
155impl AsMut<SourceFile> for ParsedFile {
156 fn as_mut(&mut self) -> &mut SourceFile {
157 self.cst_mut()
158 }
159}
160
161impl Display for ParsedFile {
162 fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
163 self.token_stream().fmt(formatter)
164 }
165}
166
167impl Spanned for ParsedFile {
168 fn span(&self) -> Span {
169 self.cst.span()
170 }
171}
172
173impl ToTokens for ParsedFile {
174 fn to_tokens(&self, output: &mut TokenStream) {
175 self.cst.to_tokens(output);
176 }
177}
178
179impl ToCells for ParsedFile {
180 fn to_cells(&self, output: &mut CellStream) {
181 self.cst.to_cells(output);
182 }
183}