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
73		let Eol = if Content.contains("\r\n") { "\r\n" } else { "\n" }.to_owned();
74
75		let Document = DocumentStateDTO {
76			URI:ParsedUri,
77
78			LanguageIdentifier:LanguageId.clone(),
79
80			Version,
81
82			Lines,
83
84			EOL:Eol,
85
86			IsDirty:false,
87
88			Encoding:"utf-8".to_owned(),
89
90			VersionIdentifier:Version,
91		};
92
93		RunTime
94			.Environment
95			.ApplicationState
96			.Feature
97			.Documents
98			.AddOrUpdate(Uri.clone(), Document);
99	}
100
101	Ok(json!({
102		"uri": Uri,
103		"content": Content,
104		"version": Version,
105		"languageId": LanguageId,
106	}))
107}