Skip to main content

Mountain/Track/Effect/CreateEffectForRequest/
FileReadAlias.rs

1#![allow(unused_variables, dead_code, unused_imports)]
2
3//! Cocoon legacy aliases: `openDocument`, `readFile`, `stat` - short-hand
4//! routes used by Cocoon's Effect-TS Workspace + FileSystem services before
5//! the canonical `FileSystem.*` naming was established. Backed by the same
6//! `FileSystemReader` provider.
7
8use std::{future::Future, pin::Pin, sync::Arc};
9
10use CommonLibrary::{Environment::Requires::Requires, FileSystem::FileSystemReader::FileSystemReader};
11use serde_json::{Value, json};
12use tauri::Runtime;
13
14use crate::{RunTime::ApplicationRunTime::ApplicationRunTime, Track::Effect::MappedEffectType::MappedEffect};
15
16/// Strip a leading `file://` (or `file:///`) scheme from the incoming path.
17/// Mirrors the helper in `FileSystem.rs`; inlined here to avoid a cross-module
18/// dependency on a private function in a sibling module.
19/// Cocoon sends full URIs like `file:///<home>/.fiddee/extensions/...` through
20/// the legacy `openDocument`/`readFile`/`stat` routes; without stripping,
21/// `PathBuf` roots at the literal scheme string and every read 404s.
22fn StripFileUriScheme(Input:&str) -> &str {
23	if let Some(Rest) = Input.strip_prefix("file://") {
24		if Rest.starts_with('/') {
25			return Rest;
26		}
27
28		if let Some(Idx) = Rest.find('/') {
29			return &Rest[Idx..];
30		}
31	}
32
33	Input
34}
35
36pub fn CreateEffect<R:Runtime>(MethodName:&str, Parameters:Value) -> Option<Result<MappedEffect, String>> {
37	match MethodName {
38		"openDocument" | "readFile" | "stat" => {
39			let MethodNameOwned = MethodName.to_string();
40
41			let effect =
42				move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
43					Box::pin(async move {
44						let fs_reader:Arc<dyn FileSystemReader> = run_time.Environment.Require();
45						let Path = if let Some(Object) = Parameters.as_object() {
46							Object
47								.get("uri")
48								.or_else(|| Object.get("path"))
49								.and_then(Value::as_str)
50								.unwrap_or("")
51								.to_string()
52						} else {
53							Parameters.get(0).and_then(Value::as_str).unwrap_or("").to_string()
54						};
55						// Empty-path guard: matches the FileSystem.* contract so that
56						// the LooksLike404 classifier in MountainVinegRPCService
57						// downgrades the log level and uses error code -32004 rather
58						// than tripping the circuit breaker with a -32000.
59						if Path.is_empty() {
60							return Err(format!("{}: empty path (resource not found)", MethodNameOwned));
61						}
62						let PathBuf_ = std::path::PathBuf::from(StripFileUriScheme(&Path));
63						match MethodNameOwned.as_str() {
64							"stat" => {
65								fs_reader
66									.StatFile(&PathBuf_)
67									.await
68									.map(|S| serde_json::to_value(S).unwrap_or(Value::Null))
69									.map_err(|e| e.to_string())
70							},
71							"readFile" | "openDocument" => {
72								fs_reader
73									.ReadFile(&PathBuf_)
74									.await
75									.map(|Bytes| {
76										let Text = String::from_utf8(Bytes).unwrap_or_default();
77										json!({ "uri": Path, "text": Text })
78									})
79									.map_err(|e| e.to_string())
80							},
81							_ => Ok(Value::Null),
82						}
83					})
84				};
85
86			Some(Ok(Box::new(effect)))
87		},
88
89		_ => None,
90	}
91}