xlsynth_prover/dslx_tactics/
source.rs1use serde::{Deserialize, Serialize};
6use std::path::PathBuf;
7
8#[derive(Clone, Debug, Serialize, Deserialize)]
9pub enum SourceFile {
10 Path(PathBuf),
11 Text(String),
12}
13
14impl SourceFile {
15 pub fn contents(&self) -> Result<String, String> {
16 match self {
17 SourceFile::Text(t) => Ok(t.clone()),
18 SourceFile::Path(p) => {
19 std::fs::read_to_string(p).map_err(|e| format!("read {:?}: {}", p, e))
20 }
21 }
22 }
23}
24
25#[derive(Clone, Debug, Serialize, Deserialize)]
26pub enum Edit {
27 AppendSource { source: SourceFile },
28}
29
30impl Edit {
31 pub fn apply(&self, current: &str) -> Result<String, String> {
32 match self {
33 Edit::AppendSource { source } => {
34 let code = source.contents()?;
35 let mut out = current.to_owned();
36 if !out.is_empty() {
37 out.push_str("\n\n");
38 }
39 out.push_str(&code);
40 Ok(out)
41 }
42 }
43 }
44}
45
46#[derive(Clone, Debug, Serialize, Deserialize)]
47pub struct FileWithHistory {
48 pub base_source: SourceFile,
49 pub edits: Vec<Edit>,
50 pub text: String,
51}
52
53impl FileWithHistory {
54 pub fn apply_edit(&mut self, edit: Edit) -> Result<(), String> {
55 self.edits.push(edit.clone());
56 self.text = edit.apply(&self.text)?;
57 Ok(())
58 }
59
60 pub fn from_text(text: &str) -> Self {
61 Self {
62 base_source: SourceFile::Text(text.to_string()),
63 edits: Vec::new(),
64 text: text.to_string(),
65 }
66 }
67
68 pub fn from_path(path: &PathBuf) -> Self {
69 let file = SourceFile::Path(path.clone());
70 let text = file.contents().unwrap();
71 Self {
72 base_source: file,
73 edits: Vec::new(),
74 text,
75 }
76 }
77}