Skip to main content

Mountain/IPC/WindServiceHandlers/Model/
ModelOpen.rs

1#![allow(non_snake_case)]
2
3//! Open a text model: read content from disk, derive language
4//! ID from the extension, register the resulting
5//! `DocumentStateDTO` in `ApplicationState.Feature.Documents`,
6//! and return `{ uri, content, version, languageId }` to Wind.
7//!
8//! Version starts at 1 for fresh opens; an existing entry
9//! increments instead of resetting so concurrent re-opens
10//! don't desync VS Code's TextDocument observers.
11
12use std::sync::Arc;
13
14use serde_json::{Value, json};
15
16use crate::{
17	ApplicationState::DTO::DocumentStateDTO::DocumentStateDTO,
18	RunTime::ApplicationRunTime::ApplicationRunTime,
19};
20
21pub async fn ModelOpen(RunTime:Arc<ApplicationRunTime>, Arguments:Vec<Value>) -> Result<Value, String> {
22	let Uri = Arguments
23		.first()
24		.and_then(|V| V.as_str())
25		.ok_or("model:open requires uri".to_string())?
26		.to_owned();
27
28	let FilePath = if let Some(stripped) = Uri.strip_prefix("file://") {
29		stripped.to_owned()
30	} else {
31		Uri.clone()
32	};
33
34	let Content = tokio::fs::read_to_string(&FilePath).await.unwrap_or_default();
35
36	let LanguageId = std::path::Path::new(&FilePath)
37		.extension()
38		.and_then(|E| E.to_str())
39		.map(|Ext| {
40			match Ext {
41				"rs" => "rust",
42				"ts" | "tsx" => "typescript",
43				"js" | "jsx" | "mjs" | "cjs" => "javascript",
44				"json" | "jsonc" => "json",
45				"toml" => "toml",
46				"yaml" | "yml" => "yaml",
47				"md" => "markdown",
48				"html" | "htm" => "html",
49				"css" | "scss" | "less" => "css",
50				"sh" | "bash" | "zsh" => "shellscript",
51				"py" => "python",
52				"go" => "go",
53				"c" | "h" => "c",
54				"cpp" | "cc" | "cxx" | "hpp" => "cpp",
55				_ => "plaintext",
56			}
57		})
58		.unwrap_or("plaintext")
59		.to_owned();
60
61	let Version = RunTime
62		.Environment
63		.ApplicationState
64		.Feature
65		.Documents
66		.Get(&Uri)
67		.map(|D| D.Version + 1)
68		.unwrap_or(1);
69
70	if let Ok(ParsedUri) = url::Url::parse(&Uri) {
71		let Lines:Vec<String> = Content.lines().map(|L| L.to_owned()).collect();
72		let Eol = if Content.contains("\r\n") { "\r\n" } else { "\n" }.to_owned();
73
74		let Document = DocumentStateDTO {
75			URI:ParsedUri,
76			LanguageIdentifier:LanguageId.clone(),
77			Version,
78			Lines,
79			EOL:Eol,
80			IsDirty:false,
81			Encoding:"utf-8".to_owned(),
82			VersionIdentifier:Version,
83		};
84
85		RunTime
86			.Environment
87			.ApplicationState
88			.Feature
89			.Documents
90			.AddOrUpdate(Uri.clone(), Document);
91	}
92
93	Ok(json!({
94		"uri": Uri,
95		"content": Content,
96		"version": Version,
97		"languageId": LanguageId,
98	}))
99}