microcad_lang/syntax/source_file/
mod.rs1use crate::{src_ref::*, syntax::*};
7
8#[derive(Clone, Debug, Default)]
10pub struct SourceFile {
11 pub name: QualifiedName,
13 pub statements: StatementList,
15 pub filename: Option<std::path::PathBuf>,
17 pub source: String,
19
20 pub hash: u64,
25}
26
27impl SourceFile {
28 pub fn filename(&self) -> std::path::PathBuf {
30 self.filename
31 .clone()
32 .unwrap_or(std::path::PathBuf::from(crate::invalid_no_ansi!(SOURCE)))
33 }
34
35 pub fn filename_as_str(&self) -> &str {
37 self.filename
38 .as_ref()
39 .map(|f| f.to_str().expect("File name error {filename:?}"))
40 .unwrap_or(crate::invalid!(SOURCE))
41 }
42
43 pub fn id(&self) -> Identifier {
45 match &self.filename {
46 Some(filename) => Identifier(Refer::new(
47 filename
48 .file_stem()
49 .expect("cannot get file stem")
50 .to_str()
51 .expect("File name error {filename:?}")
52 .into(),
53 SrcRef::new(0..0, 0, 0, self.hash),
54 )),
55 None => Identifier::none(),
56 }
57 }
58
59 pub fn get_line(&self, line: usize) -> Option<&str> {
63 self.source.lines().nth(line)
64 }
65
66 pub fn num_lines(&self) -> usize {
68 self.source.lines().count()
69 }
70}
71impl std::fmt::Display for SourceFile {
72 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73 self.statements.iter().try_for_each(|s| writeln!(f, "{s}"))
74 }
75}
76
77impl TreeDisplay for SourceFile {
78 fn tree_print(&self, f: &mut std::fmt::Formatter, mut depth: TreeState) -> std::fmt::Result {
79 writeln!(
80 f,
81 "{:depth$}SourceFile '{:?}' ({}):",
82 "",
83 self.id(),
84 self.filename_as_str()
85 )?;
86 depth.indent();
87 self.statements
88 .iter()
89 .try_for_each(|s| s.tree_print(f, depth))
90 }
91}
92
93impl SrcReferrer for SourceFile {
94 fn src_ref(&self) -> crate::src_ref::SrcRef {
95 SrcRef::new(0..self.num_lines(), 0, 0, self.hash)
96 }
97}
98
99#[test]
100fn load_source_file_wrong_location() {
101 let source_file = SourceFile::load("I do not exist.µcad");
102 if let Err(err) = source_file {
103 log::info!("{err}");
104 } else {
106 panic!("Does file exist?");
107 }
108}