Mountain/FileSystem/
FileExplorerViewProvider.rs1#![allow(non_snake_case, non_camel_case_types)]
19
20use std::sync::Arc;
21
22use Common::{
23 Effect::ApplicationRunTime::ApplicationRunTime,
24 Environment::Environment::Environment,
25 Error::CommonError::CommonError,
26 FileSystem::{DTO::FileTypeDTO::FileTypeDTO, ReadDirectory::ReadDirectory},
27 TreeView::TreeViewProvider::TreeViewProvider,
28};
29use async_trait::async_trait;
30use log::info;
31use serde_json::{Value, json};
32use tauri::{AppHandle, Manager};
34use url::Url;
35
36use crate::RunTime::ApplicationRunTime::ApplicationRunTime as MountainRunTime;
37
38#[derive(Clone)]
39pub struct FileExplorerViewProvider {
40 AppicationHandle:AppHandle,
41}
42
43impl Environment for FileExplorerViewProvider {}
44
45impl FileExplorerViewProvider {
46 pub fn New(AppicationHandle:AppHandle) -> Self { Self { AppicationHandle } }
47
48 fn CreateTreeItemDTO(&self, Name:&str, Uri:&Url, FileType:FileTypeDTO) -> Value {
50 json!({
51
52 "handle": Uri.to_string(),
53
54 "label": { "label": Name },
55
56 "collapsibleState": if FileType == FileTypeDTO::Directory { 1 } else { 0 },
58
59 "resourceUri": json!({ "external": Uri.to_string() }),
60
61 "command": if FileType == FileTypeDTO::File {
62
63 Some(json!({
64
65 "id": "vscode.open",
66
67 "title": "Open File",
68
69 "arguments": [json!({ "external": Uri.to_string() })]
70 }))
71 } else {
72
73 None
74 }
75
76 })
77 }
78}
79
80#[async_trait]
81impl TreeViewProvider for FileExplorerViewProvider {
82 async fn RegisterTreeDataProvider(&self, _ViewIdentifier:String, _Options:Value) -> Result<(), CommonError> {
84 Ok(())
85 }
86
87 async fn UnregisterTreeDataProvider(&self, _ViewIdentifier:String) -> Result<(), CommonError> { Ok(()) }
88
89 async fn RevealTreeItem(
90 &self,
91
92 _ViewIdentifier:String,
93
94 _ItemHandle:String,
95
96 _Options:Value,
97 ) -> Result<(), CommonError> {
98 Ok(())
99 }
100
101 async fn RefreshTreeView(&self, _ViewIdentifier:String, _ItemsToRefresh:Option<Value>) -> Result<(), CommonError> {
102 Ok(())
103 }
104
105 async fn SetTreeViewMessage(&self, _ViewIdentifier:String, _Message:Option<String>) -> Result<(), CommonError> {
106 Ok(())
107 }
108
109 async fn SetTreeViewTitle(
110 &self,
111
112 _ViewIdentifier:String,
113
114 _Title:Option<String>,
115
116 _Description:Option<String>,
117 ) -> Result<(), CommonError> {
118 Ok(())
119 }
120
121 async fn SetTreeViewBadge(&self, _ViewIdentifier:String, _BadgeValue:Option<Value>) -> Result<(), CommonError> {
122 Ok(())
123 }
124
125 async fn GetChildren(
129 &self,
130
131 _ViewIdentifier:String,
133
134 ElementHandle:Option<String>,
135 ) -> Result<Vec<Value>, CommonError> {
136 let RunTime = self.AppicationHandle.state::<Arc<MountainRunTime>>().inner().clone();
137
138 let AppState = RunTime.Environment.ApplicationState.clone();
139
140 let PathToRead = if let Some(Handle) = ElementHandle {
141 Url::parse(&Handle)
143 .map_err(|_| {
144 CommonError::InvalidArgument {
145 ArgumentName:"ElementHandle".into(),
146
147 Reason:"Handle is not a valid URI".into(),
148 }
149 })?
150 .to_file_path()
151 .map_err(|_| {
152 CommonError::InvalidArgument {
153 ArgumentName:"ElementHandle".into(),
154
155 Reason:"Handle URI is not a file path".into(),
156 }
157 })?
158 } else {
159 let Folders = AppState.WorkSpaceFolders.lock().unwrap();
161
162 let RootItems:Vec<Value> = Folders
163 .iter()
164 .map(|folder| self.CreateTreeItemDTO(&folder.Name, &folder.URI, FileTypeDTO::Directory))
165 .collect();
166
167 return Ok(RootItems);
168 };
169
170 info!("[FileExplorer] Getting children for path: {}", PathToRead.display());
171
172 let Entries = RunTime.Run(ReadDirectory(PathToRead.clone())).await?;
175
176 let Items = Entries
177 .into_iter()
178 .map(|(Name, FileType)| {
179 let FullPath = PathToRead.join(&Name);
180
181 let Uri = Url::from_file_path(FullPath).unwrap();
182
183 self.CreateTreeItemDTO(&Name, &Uri, FileType)
184 })
185 .collect();
186
187 Ok(Items)
188 }
189
190 async fn GetTreeItem(&self, _ViewIdentifier:String, ElementHandle:String) -> Result<Value, CommonError> {
192 let URI = Url::parse(&ElementHandle).map_err(|Error| {
193 CommonError::InvalidArgument { ArgumentName:"ElementHandle".into(), Reason:Error.to_string() }
194 })?;
195
196 let Name = URI.path_segments().and_then(|s| s.last()).unwrap_or("").to_string();
197
198 let IsDirectory = URI.as_str().ends_with('/') || URI.to_file_path().map_or(false, |p| p.is_dir());
200
201 let FileType = if IsDirectory { FileTypeDTO::Directory } else { FileTypeDTO::File };
202
203 Ok(self.CreateTreeItemDTO(&Name, &URI, FileType))
204 }
205}