Skip to content

Commit d5753a9

Browse files
authored
Merge pull request #150 from j-mie6/main
v0.4.3
2 parents 1a9584c + 7d44650 commit d5753a9

File tree

14 files changed

+165
-134
lines changed

14 files changed

+165
-134
lines changed

backend/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "dill"
3-
version = "0.4.0"
3+
version = "0.4.3"
44
description = "A cross-platform debugging UI for `parsley-debug`"
55
authors = ["Jamie Willis (@j-mie6)", "Josh Walker (@josh-ja-walker)", "Aniket Gupta (@aniket1101)", "Priyansh Chugh (@PriyanshC)", "Alejandro Perez Fadon (@Aito0)", "Riley Horrix (@Riley-horrix)", "Adam Watson (@AdamW1087)"]
66
license = "BSD 3-Clause"

backend/src/commands.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ pub fn handlers() -> impl Fn(tauri::ipc::Invoke) -> bool {
88
fetch::fetch_debug_tree,
99
fetch::fetch_node_children,
1010
save::save_tree,
11-
save::fetch_saved_tree_names,
1211
save::load_saved_tree,
1312
save::delete_tree,
1413
breakpoint::skip_breakpoints,

backend/src/commands/save.rs

Lines changed: 28 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ use crate::files::SAVED_TREE_DIR;
99

1010
/* Saves current tree to saved_trees/name.json */
1111
#[tauri::command]
12-
pub fn save_tree(state: tauri::State<AppState>, tree_name: String) -> Result<(), SaveTreeError> {
12+
pub fn save_tree(state: tauri::State<AppState>, tree_name: String) -> Result<String, SaveTreeError> {
1313
/* Access the `tree` field from the locked state */
1414
let saved_tree: SavedTree = SavedTree::from(state.get_tree()?);
15-
15+
1616
/* Get the serialised JSON */
1717
let tree_json: String = serde_json::to_string_pretty(&saved_tree)
1818
.map_err(|_| SaveTreeError::SerialiseFailed)?;
@@ -24,8 +24,12 @@ pub fn save_tree(state: tauri::State<AppState>, tree_name: String) -> Result<(),
2424

2525
/* Write tree json to the json file */
2626
data_file.write(tree_json.as_bytes()).map_err(|_| SaveTreeError::WriteTreeFailed)?;
27+
28+
/* Get a list of all saved tree names */
29+
let tree_names: Vec<String> = state.add_tree(tree_name).map_err(|_| SaveTreeError::AddTreeFailed)?;
2730

28-
Ok(())
31+
serde_json::to_string_pretty(&tree_names)
32+
.map_err(|_| SaveTreeError::SerialiseFailed)
2933
}
3034

3135
#[derive(Debug, serde::Serialize)]
@@ -35,6 +39,7 @@ pub enum SaveTreeError {
3539
SerialiseFailed,
3640
CreateDirFailed,
3741
WriteTreeFailed,
42+
AddTreeFailed,
3843
}
3944

4045
impl From<StateError> for SaveTreeError {
@@ -50,63 +55,49 @@ impl From<StateError> for SaveTreeError {
5055

5156
/* Delete file associated with where tree is saved */
5257
#[tauri::command]
53-
pub fn delete_tree(tree_name: String) -> Result<(), DeleteTreeError> {
58+
pub fn delete_tree(state: tauri::State<AppState>, index: usize) -> Result<String, DeleteTreeError> {
59+
/* Get the tree name given the index */
60+
let tree_name: String = state.get_tree_name(index).map_err(|_| DeleteTreeError::NameRetrievalFail)?;
61+
5462
/* Path to the json file used to store the tree */
5563
let file_path: String = format!("{}{}.json", SAVED_TREE_DIR, tree_name);
5664

5765
/* Remove the file from the file system */
5866
fs::remove_file(file_path).map_err(|_| DeleteTreeError::TreeFileRemoveFail)?;
59-
Ok(())
60-
}
61-
62-
#[derive(Debug, serde::Serialize)]
63-
pub enum DeleteTreeError {
64-
TreeFileRemoveFail,
65-
}
6667

68+
/* Returns a list of the tree names that are left */
69+
let tree_names: Vec<String> = state.rmv_tree(index).map_err(|_| DeleteTreeError::TreeRemovalFail)?;
6770

68-
/* Returns a list of filenames in saved_trees */
69-
#[tauri::command]
70-
pub fn fetch_saved_tree_names() -> Result<String, FetchTreeNameError> {
71-
/* Get all path names inside the saved_trees folder */
72-
let paths: fs::ReadDir = fs::read_dir(SAVED_TREE_DIR).map_err(|_| FetchTreeNameError::ReadDirFailed)?;
73-
74-
/* Strip off the extension and add only the name to names */
75-
let names: Vec<String> = paths.into_iter()
76-
.map(|path| {
77-
let path: fs::DirEntry = path.map_err(|_| FetchTreeNameError::ReadPathFailed)?;
78-
let file_name: String = path.file_name().into_string().map_err(|_| FetchTreeNameError::StringContainsInvalidUnicode)?;
79-
let name: &str = file_name.strip_suffix(".json").ok_or(FetchTreeNameError::SuffixNotFound)?;
80-
Ok(name.to_string())
81-
}).collect::<Result<Vec<String>, FetchTreeNameError>>()?;
82-
83-
/* Serialise names */
84-
serde_json::to_string_pretty(&names)
85-
.map_err(|_| FetchTreeNameError::SerialiseFailed)
71+
serde_json::to_string_pretty(&tree_names)
72+
.map_err(|_| DeleteTreeError::SerialiseFailed)
8673
}
8774

8875
#[derive(Debug, serde::Serialize)]
89-
pub enum FetchTreeNameError {
90-
ReadDirFailed,
91-
ReadPathFailed,
92-
StringContainsInvalidUnicode,
93-
SuffixNotFound,
76+
pub enum DeleteTreeError {
77+
TreeFileRemoveFail,
78+
NameRetrievalFail,
79+
TreeRemovalFail,
9480
SerialiseFailed,
9581
}
9682

9783

9884
/* Fetches a tree from saved_trees and resets the tree in the tauri state */
9985
#[tauri::command]
100-
pub fn load_saved_tree(tree_name: String, state: tauri::State<AppState>) -> Result<(), LoadTreeError> {
86+
pub fn load_saved_tree(index: usize, state: tauri::State<AppState>) -> Result<(), LoadTreeError> {
87+
/* Get the tree name given the index */
88+
let tree_name: String = state.get_tree_name(index).map_err(|_| LoadTreeError::NameRetrievalFail)?;
89+
10190
/* Get the file path of the tree to be reloaded */
10291
let file_path: String = format!("{}{}.json", SAVED_TREE_DIR, tree_name);
103-
92+
10493
/* Read the contents of the file as a string */
10594
let contents: String = fs::read_to_string(file_path)
10695
.map_err(|_| LoadTreeError::ReadFileFailed)?;
10796

97+
10898
/* Deserialize the tree into SavedTree, then convert to DebugTree */
10999
let saved_tree: SavedTree = serde_json::from_str(&contents).map_err(|_| LoadTreeError::DeserialiseFailed)?;
100+
110101
let tree: DebugTree = DebugTree::from(saved_tree);
111102

112103
/* Update the global tauri state with the reloaded tree */
@@ -118,6 +109,7 @@ pub fn load_saved_tree(tree_name: String, state: tauri::State<AppState>) -> Resu
118109
#[derive(Debug, serde::Serialize)]
119110
#[allow(clippy::enum_variant_names)]
120111
pub enum LoadTreeError {
112+
NameRetrievalFail,
121113
LockFailed,
122114
ReadFileFailed,
123115
DeserialiseFailed,

backend/src/state/app_state.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ struct AppStateInternal {
1515
tree: Option<DebugTree>, /* Parser tree that is posted to Server */
1616
map: HashMap<u32, DebugNode>, /* Map from node_id to the respective node */
1717
skips_tx: TokioMutex<SkipsSender>, /* Transmitter how many breakpoints to skip, sent to parsley */
18+
tab_names: Vec<String>, /* List of saved tree names */
1819
}
1920

2021

@@ -31,6 +32,7 @@ impl AppState {
3132
tree: None,
3233
map: HashMap::new(),
3334
skips_tx,
35+
tab_names: Vec::new(),
3436
}
3537
)
3638
)
@@ -41,6 +43,39 @@ impl AppState {
4143
self.0.lock()
4244
.map_err(|_| StateError::LockFailed)
4345
}
46+
47+
/* Add tree name to tab_names */
48+
pub fn add_tree(&self, new_tab: String) -> Result<Vec<String>, StateError> {
49+
let mut state: MutexGuard<AppStateInternal> = self.inner()?;
50+
51+
/* Add new tree name and return all saved tree names */
52+
state.tab_names.push(new_tab);
53+
54+
Ok(state.tab_names.clone())
55+
}
56+
57+
/* Remove tree name from tab_names */
58+
pub fn rmv_tree(&self, index: usize) -> Result<Vec<String>, StateError> {
59+
let mut state: MutexGuard<AppStateInternal> = self.inner()?;
60+
61+
/* Remove tree name at index */
62+
state.tab_names.remove(index);
63+
64+
/* If this was the final tree then the loaded tree needs to be removed */
65+
if state.tab_names.is_empty() {
66+
state.tree = None
67+
}
68+
69+
Ok(state.tab_names.clone())
70+
}
71+
72+
/* Given an index returns the tree name */
73+
pub fn get_tree_name(&self, index: usize) -> Result<String, StateError> {
74+
let state: MutexGuard<AppStateInternal> = self.inner()?;
75+
76+
/* Index will never be out of range as the frontend representation and the backend will be in sync */
77+
Ok(state.tab_names[index].clone())
78+
}
4479
}
4580

4681

backend/tauri.conf.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
33
"productName": "dill",
4-
"version": "0.4.0",
4+
"version": "0.4.3",
55
"identifier": "com.dill.dev",
66
"build": {
77
"frontendDist": "../dist",

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ val Scala3 = "3.6.3"
77

88
val scalatestVersion = "3.2.19"
99

10-
val Version = "0.4.0"
10+
val Version = "0.4.3"
1111

1212
Global / onChangedBuildSource := ReloadOnSourceChanges
1313
Global / excludeLintKeys += dillFrontend / Compile / stMinimize

frontend/src/main/scala/controller/tauri/Command.scala

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -83,34 +83,27 @@ object Command {
8383
def namedArgs: Map[String, Any] = Map("treeName" -> treeName)
8484
}
8585

86-
type Out = Unit
87-
}
88-
89-
case object FetchSavedTreeNames extends Command("fetch_saved_tree_names") {
90-
type In = Unit
91-
given args: Args[In] = Args.noArgs
92-
9386
type Out = List[String]
9487
}
9588

9689
case object LoadSavedTree extends Command("load_saved_tree") {
97-
type In = String
98-
given args: Args[String] {
99-
extension (treeName: String)
100-
def namedArgs: Map[String, Any] = Map("treeName" -> treeName)
90+
type In = Int
91+
given args: Args[Int] {
92+
extension (index: Int)
93+
def namedArgs: Map[String, Any] = Map("index" -> index)
10194
}
10295

10396
type Out = Unit
10497
}
10598

10699
case object DeleteTree extends Command("delete_tree") {
107-
type In = String
108-
given args: Args[String] {
109-
extension (treeName: String)
110-
def namedArgs: Map[String, Any] = Map("treeName" -> treeName)
100+
type In = Int
101+
given args: Args[Int] {
102+
extension (index: Int)
103+
def namedArgs: Map[String, Any] = Map("index" -> index)
111104
}
112105

113-
type Out = Unit
106+
type Out = List[String]
114107
}
115108

116109
case object SkipBreakpoints extends Command("skip_breakpoints") {

frontend/src/main/scala/controller/viewControllers/TabViewController.scala

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,43 +28,30 @@ object TabViewController {
2828

2929
/** Set file names */
3030
val setFileNames: Observer[List[String]] = fileNames.writer
31-
32-
/** Add name to file names */
33-
val addFileName: Observer[String] = fileNames.updater((names, name) => names :+ name)
34-
35-
/** Fetches all tree names saved by the user from the backend */
36-
def loadFileNames: EventStream[Either[DillException, List[String]]] = Tauri.invoke(Command.FetchSavedTreeNames, ())
3731

3832
/** Returns true if there are no saved trees */
3933
def noSavedTrees: Signal[Boolean] = getFileNames.signal.map(_.isEmpty)
4034

41-
35+
4236
/* Index of tab that is currented selected */
4337
private lazy val selectedTab: Var[Int] = Var(0)
4438

4539
/** Set current selected tab index */
4640
val setSelectedTab: Observer[Int] = selectedTab.writer
4741

48-
/** Get index of tab with associated name */
49-
def getFileNameIndex(name: String): Signal[Int] = getFileNames.map(_.indexOf(name))
50-
5142
/** Get selected tab index */
5243
val getSelectedTab: Signal[Int] = selectedTab.signal
5344

54-
/** Get name of tree associated with selected tab */
55-
def getSelectedFileName: Signal[String] = getSelectedTab.flatMapSwitch(getFileName)
56-
5745
/** Checks if tab is currently selected */
5846
def tabSelected(index: Int): Signal[Boolean] = getSelectedTab.map(_ == index)
5947

6048

6149
/** Saves current tree to the backend with given name, returning assigned tab index */
62-
def saveTree(name: String): EventStream[Either[DillException, Unit]] = Tauri.invoke(Command.SaveTree, name)
50+
def saveTree(name: String): EventStream[Either[DillException, List[String]]] = Tauri.invoke(Command.SaveTree, name)
6351

6452
/** Loads a saved tree from the backend as DebugTree */
65-
def loadSavedTree(name: String): EventStream[Either[DillException, Unit]] = Tauri.invoke(Command.LoadSavedTree, name)
53+
def loadSavedTree(index: Int): EventStream[Either[DillException, Unit]] = Tauri.invoke(Command.LoadSavedTree, index)
6654

6755
/** Delete tree loaded within tab, returning updated list of names */
68-
def deleteSavedTree(name: String): EventStream[Either[DillException, Unit]] = Tauri.invoke(Command.DeleteTree, name)
69-
56+
def deleteSavedTree(index: Int): EventStream[Either[DillException, List[String]]] = Tauri.invoke(Command.DeleteTree, index)
7057
}

0 commit comments

Comments
 (0)