Mountain/ApplicationState/DTO/
DocumentStateDTO.rs1#![allow(non_snake_case, non_camel_case_types)]
7
8use Common::Error::CommonError::CommonError;
9use serde::{Deserialize, Serialize};
10use serde_json::Value;
11use url::Url;
12
13use super::RPCModelContentChangeDTO::RPCModelContentChangeDTO;
14use crate::ApplicationState::Internal::{AnalyzeTextLinesAndEOL, URLSerializationHelper};
15
16#[derive(Serialize, Deserialize, Clone, Debug)]
18#[serde(rename_all = "PascalCase")]
19pub struct DocumentStateDTO {
20 #[serde(with = "URLSerializationHelper")]
22 pub URI:Url,
23
24 pub LanguageIdentifier:String,
26
27 pub Version:i64,
29
30 pub Lines:Vec<String>,
32
33 pub EOL:String,
35
36 pub IsDirty:bool,
38
39 pub Encoding:String,
41
42 pub VersionIdentifier:i64,
44}
45
46impl DocumentStateDTO {
47 pub fn Create(URI:Url, LanguageIdentifier:Option<String>, Content:String) -> Self {
49 let (Lines, EOL) = AnalyzeTextLinesAndEOL(&Content);
50
51 let LanguageID = LanguageIdentifier.unwrap_or_else(|| "plaintext".to_string());
52
53 let Encoding = "utf8".to_string();
54
55 Self {
56 URI,
57
58 LanguageIdentifier:LanguageID,
59
60 Version:1,
61
62 Lines,
63
64 EOL,
65
66 IsDirty:false,
67
68 Encoding,
69
70 VersionIdentifier:1,
71 }
72 }
73
74 pub fn GetText(&self) -> String { self.Lines.join(&self.EOL) }
76
77 pub fn ToDTO(&self) -> Result<Value, CommonError> {
79 serde_json::to_value(self).map_err(|Error| CommonError::SerializationError { Description:Error.to_string() })
80 }
81
82 pub fn ApplyChanges(&mut self, NewVersion:i64, ChangesValue:&Value) -> Result<(), CommonError> {
85 if NewVersion <= self.Version {
87 return Ok(());
88 }
89
90 if let Ok(RPCChange) = serde_json::from_value::<Vec<RPCModelContentChangeDTO>>(ChangesValue.clone()) {
92 log::warn!(
96 "Applying changes to {} by version bump only (delta application is a stub).",
97 self.URI
98 );
99
100 self.Lines = ApplyDeltaChanges(&self.Lines, &self.EOL, &RPCChange);
102 } else if let Some(FullText) = ChangesValue.as_str() {
103 let (NewLines, NewEOL) = AnalyzeTextLinesAndEOL(FullText);
105
106 self.Lines = NewLines;
107
108 self.EOL = NewEOL;
109 } else {
110 return Err(CommonError::InvalidArgument {
111 ArgumentName:"ChangesValue".into(),
112
113 Reason:format!(
114 "Invalid change format for {}: expected string or RPCModelContentChangeDTO array.",
115 self.URI
116 ),
117 });
118 }
119
120 self.Version = NewVersion;
122
123 self.VersionIdentifier += 1;
124
125 self.IsDirty = true;
126
127 Ok(())
128 }
129}
130
131fn ApplyDeltaChanges(_Line:&[String], _EOL:&str, _RPCChange:&[RPCModelContentChangeDTO]) -> Vec<String> { todo!() }