1use schemars::JsonSchema;
8use serde::{Deserialize, Serialize};
9use serde_with::{DefaultOnError, VecSkipError, serde_as, skip_serializing_none};
10
11use crate::{IntoOption, Meta, SessionId, SkipListener};
12
13pub(crate) const NES_START_METHOD_NAME: &str = "nes/start";
17pub(crate) const NES_SUGGEST_METHOD_NAME: &str = "nes/suggest";
19pub(crate) const NES_ACCEPT_METHOD_NAME: &str = "nes/accept";
21pub(crate) const NES_REJECT_METHOD_NAME: &str = "nes/reject";
23pub(crate) const NES_CLOSE_METHOD_NAME: &str = "nes/close";
25pub(crate) const DOCUMENT_DID_OPEN_METHOD_NAME: &str = "document/didOpen";
27pub(crate) const DOCUMENT_DID_CHANGE_METHOD_NAME: &str = "document/didChange";
29pub(crate) const DOCUMENT_DID_CLOSE_METHOD_NAME: &str = "document/didClose";
31pub(crate) const DOCUMENT_DID_SAVE_METHOD_NAME: &str = "document/didSave";
33pub(crate) const DOCUMENT_DID_FOCUS_METHOD_NAME: &str = "document/didFocus";
35
36#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
42#[non_exhaustive]
43pub enum PositionEncodingKind {
44 #[serde(rename = "utf-16")]
46 Utf16,
47 #[serde(rename = "utf-32")]
49 Utf32,
50 #[serde(rename = "utf-8")]
52 Utf8,
53}
54
55#[skip_serializing_none]
59#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
60#[serde(rename_all = "camelCase")]
61#[non_exhaustive]
62pub struct Position {
63 pub line: u32,
65 pub character: u32,
67 #[serde(rename = "_meta")]
73 pub meta: Option<Meta>,
74}
75
76impl Position {
77 #[must_use]
79 pub fn new(line: u32, character: u32) -> Self {
80 Self {
81 line,
82 character,
83 meta: None,
84 }
85 }
86
87 #[must_use]
93 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
94 self.meta = meta.into_option();
95 self
96 }
97}
98
99#[skip_serializing_none]
101#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
102#[serde(rename_all = "camelCase")]
103#[non_exhaustive]
104pub struct Range {
105 pub start: Position,
107 pub end: Position,
109 #[serde(rename = "_meta")]
115 pub meta: Option<Meta>,
116}
117
118impl Range {
119 #[must_use]
121 pub fn new(start: Position, end: Position) -> Self {
122 Self {
123 start,
124 end,
125 meta: None,
126 }
127 }
128
129 #[must_use]
135 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
136 self.meta = meta.into_option();
137 self
138 }
139}
140
141#[serde_as]
145#[skip_serializing_none]
146#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
147#[serde(rename_all = "camelCase")]
148#[non_exhaustive]
149pub struct NesCapabilities {
150 #[serde_as(deserialize_as = "DefaultOnError")]
152 #[schemars(extend("x-deserialize-default-on-error" = true))]
153 #[serde(default)]
154 pub events: Option<NesEventCapabilities>,
155 #[serde_as(deserialize_as = "DefaultOnError")]
157 #[schemars(extend("x-deserialize-default-on-error" = true))]
158 #[serde(default)]
159 pub context: Option<NesContextCapabilities>,
160 #[serde(rename = "_meta")]
166 pub meta: Option<Meta>,
167}
168
169impl NesCapabilities {
170 #[must_use]
172 pub fn new() -> Self {
173 Self::default()
174 }
175
176 #[must_use]
178 pub fn events(mut self, events: impl IntoOption<NesEventCapabilities>) -> Self {
179 self.events = events.into_option();
180 self
181 }
182
183 #[must_use]
185 pub fn context(mut self, context: impl IntoOption<NesContextCapabilities>) -> Self {
186 self.context = context.into_option();
187 self
188 }
189
190 #[must_use]
196 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
197 self.meta = meta.into_option();
198 self
199 }
200}
201
202#[serde_as]
204#[skip_serializing_none]
205#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
206#[serde(rename_all = "camelCase")]
207#[non_exhaustive]
208pub struct NesEventCapabilities {
209 #[serde_as(deserialize_as = "DefaultOnError")]
211 #[schemars(extend("x-deserialize-default-on-error" = true))]
212 #[serde(default)]
213 pub document: Option<NesDocumentEventCapabilities>,
214 #[serde(rename = "_meta")]
220 pub meta: Option<Meta>,
221}
222
223impl NesEventCapabilities {
224 #[must_use]
226 pub fn new() -> Self {
227 Self::default()
228 }
229
230 #[must_use]
232 pub fn document(mut self, document: impl IntoOption<NesDocumentEventCapabilities>) -> Self {
233 self.document = document.into_option();
234 self
235 }
236
237 #[must_use]
243 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
244 self.meta = meta.into_option();
245 self
246 }
247}
248
249#[serde_as]
251#[skip_serializing_none]
252#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
253#[serde(rename_all = "camelCase")]
254#[non_exhaustive]
255pub struct NesDocumentEventCapabilities {
256 #[serde_as(deserialize_as = "DefaultOnError")]
258 #[schemars(extend("x-deserialize-default-on-error" = true))]
259 #[serde(default)]
260 pub did_open: Option<NesDocumentDidOpenCapabilities>,
261 #[serde_as(deserialize_as = "DefaultOnError")]
263 #[schemars(extend("x-deserialize-default-on-error" = true))]
264 #[serde(default)]
265 pub did_change: Option<NesDocumentDidChangeCapabilities>,
266 #[serde_as(deserialize_as = "DefaultOnError")]
268 #[schemars(extend("x-deserialize-default-on-error" = true))]
269 #[serde(default)]
270 pub did_close: Option<NesDocumentDidCloseCapabilities>,
271 #[serde_as(deserialize_as = "DefaultOnError")]
273 #[schemars(extend("x-deserialize-default-on-error" = true))]
274 #[serde(default)]
275 pub did_save: Option<NesDocumentDidSaveCapabilities>,
276 #[serde_as(deserialize_as = "DefaultOnError")]
278 #[schemars(extend("x-deserialize-default-on-error" = true))]
279 #[serde(default)]
280 pub did_focus: Option<NesDocumentDidFocusCapabilities>,
281 #[serde(rename = "_meta")]
287 pub meta: Option<Meta>,
288}
289
290impl NesDocumentEventCapabilities {
291 #[must_use]
293 pub fn new() -> Self {
294 Self::default()
295 }
296
297 #[must_use]
299 pub fn did_open(mut self, did_open: impl IntoOption<NesDocumentDidOpenCapabilities>) -> Self {
300 self.did_open = did_open.into_option();
301 self
302 }
303
304 #[must_use]
306 pub fn did_change(
307 mut self,
308 did_change: impl IntoOption<NesDocumentDidChangeCapabilities>,
309 ) -> Self {
310 self.did_change = did_change.into_option();
311 self
312 }
313
314 #[must_use]
316 pub fn did_close(
317 mut self,
318 did_close: impl IntoOption<NesDocumentDidCloseCapabilities>,
319 ) -> Self {
320 self.did_close = did_close.into_option();
321 self
322 }
323
324 #[must_use]
326 pub fn did_save(mut self, did_save: impl IntoOption<NesDocumentDidSaveCapabilities>) -> Self {
327 self.did_save = did_save.into_option();
328 self
329 }
330
331 #[must_use]
333 pub fn did_focus(
334 mut self,
335 did_focus: impl IntoOption<NesDocumentDidFocusCapabilities>,
336 ) -> Self {
337 self.did_focus = did_focus.into_option();
338 self
339 }
340
341 #[must_use]
347 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
348 self.meta = meta.into_option();
349 self
350 }
351}
352
353#[skip_serializing_none]
355#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
356#[serde(rename_all = "camelCase")]
357#[non_exhaustive]
358pub struct NesDocumentDidOpenCapabilities {
359 #[serde(rename = "_meta")]
365 pub meta: Option<Meta>,
366}
367
368impl NesDocumentDidOpenCapabilities {
369 #[must_use]
371 pub fn new() -> Self {
372 Self::default()
373 }
374}
375
376#[skip_serializing_none]
378#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
379#[serde(rename_all = "camelCase")]
380#[non_exhaustive]
381pub struct NesDocumentDidChangeCapabilities {
382 pub sync_kind: TextDocumentSyncKind,
384 #[serde(rename = "_meta")]
390 pub meta: Option<Meta>,
391}
392
393impl NesDocumentDidChangeCapabilities {
394 #[must_use]
396 pub fn new(sync_kind: TextDocumentSyncKind) -> Self {
397 Self {
398 sync_kind,
399 meta: None,
400 }
401 }
402
403 #[must_use]
409 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
410 self.meta = meta.into_option();
411 self
412 }
413}
414
415#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
417#[non_exhaustive]
418pub enum TextDocumentSyncKind {
419 #[serde(rename = "full")]
421 Full,
422 #[serde(rename = "incremental")]
424 Incremental,
425}
426
427#[skip_serializing_none]
429#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
430#[serde(rename_all = "camelCase")]
431#[non_exhaustive]
432pub struct NesDocumentDidCloseCapabilities {
433 #[serde(rename = "_meta")]
439 pub meta: Option<Meta>,
440}
441
442impl NesDocumentDidCloseCapabilities {
443 #[must_use]
445 pub fn new() -> Self {
446 Self::default()
447 }
448}
449
450#[skip_serializing_none]
452#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
453#[serde(rename_all = "camelCase")]
454#[non_exhaustive]
455pub struct NesDocumentDidSaveCapabilities {
456 #[serde(rename = "_meta")]
462 pub meta: Option<Meta>,
463}
464
465impl NesDocumentDidSaveCapabilities {
466 #[must_use]
468 pub fn new() -> Self {
469 Self::default()
470 }
471}
472
473#[skip_serializing_none]
475#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
476#[serde(rename_all = "camelCase")]
477#[non_exhaustive]
478pub struct NesDocumentDidFocusCapabilities {
479 #[serde(rename = "_meta")]
485 pub meta: Option<Meta>,
486}
487
488impl NesDocumentDidFocusCapabilities {
489 #[must_use]
491 pub fn new() -> Self {
492 Self::default()
493 }
494}
495
496#[serde_as]
498#[skip_serializing_none]
499#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
500#[serde(rename_all = "camelCase")]
501#[non_exhaustive]
502pub struct NesContextCapabilities {
503 #[serde_as(deserialize_as = "DefaultOnError")]
505 #[schemars(extend("x-deserialize-default-on-error" = true))]
506 #[serde(default)]
507 pub recent_files: Option<NesRecentFilesCapabilities>,
508 #[serde_as(deserialize_as = "DefaultOnError")]
510 #[schemars(extend("x-deserialize-default-on-error" = true))]
511 #[serde(default)]
512 pub related_snippets: Option<NesRelatedSnippetsCapabilities>,
513 #[serde_as(deserialize_as = "DefaultOnError")]
515 #[schemars(extend("x-deserialize-default-on-error" = true))]
516 #[serde(default)]
517 pub edit_history: Option<NesEditHistoryCapabilities>,
518 #[serde_as(deserialize_as = "DefaultOnError")]
520 #[schemars(extend("x-deserialize-default-on-error" = true))]
521 #[serde(default)]
522 pub user_actions: Option<NesUserActionsCapabilities>,
523 #[serde_as(deserialize_as = "DefaultOnError")]
525 #[schemars(extend("x-deserialize-default-on-error" = true))]
526 #[serde(default)]
527 pub open_files: Option<NesOpenFilesCapabilities>,
528 #[serde_as(deserialize_as = "DefaultOnError")]
530 #[schemars(extend("x-deserialize-default-on-error" = true))]
531 #[serde(default)]
532 pub diagnostics: Option<NesDiagnosticsCapabilities>,
533 #[serde(rename = "_meta")]
539 pub meta: Option<Meta>,
540}
541
542impl NesContextCapabilities {
543 #[must_use]
545 pub fn new() -> Self {
546 Self::default()
547 }
548
549 #[must_use]
551 pub fn recent_files(
552 mut self,
553 recent_files: impl IntoOption<NesRecentFilesCapabilities>,
554 ) -> Self {
555 self.recent_files = recent_files.into_option();
556 self
557 }
558
559 #[must_use]
561 pub fn related_snippets(
562 mut self,
563 related_snippets: impl IntoOption<NesRelatedSnippetsCapabilities>,
564 ) -> Self {
565 self.related_snippets = related_snippets.into_option();
566 self
567 }
568
569 #[must_use]
571 pub fn edit_history(
572 mut self,
573 edit_history: impl IntoOption<NesEditHistoryCapabilities>,
574 ) -> Self {
575 self.edit_history = edit_history.into_option();
576 self
577 }
578
579 #[must_use]
581 pub fn user_actions(
582 mut self,
583 user_actions: impl IntoOption<NesUserActionsCapabilities>,
584 ) -> Self {
585 self.user_actions = user_actions.into_option();
586 self
587 }
588
589 #[must_use]
591 pub fn open_files(mut self, open_files: impl IntoOption<NesOpenFilesCapabilities>) -> Self {
592 self.open_files = open_files.into_option();
593 self
594 }
595
596 #[must_use]
598 pub fn diagnostics(mut self, diagnostics: impl IntoOption<NesDiagnosticsCapabilities>) -> Self {
599 self.diagnostics = diagnostics.into_option();
600 self
601 }
602
603 #[must_use]
609 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
610 self.meta = meta.into_option();
611 self
612 }
613}
614
615#[skip_serializing_none]
617#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
618#[serde(rename_all = "camelCase")]
619#[non_exhaustive]
620pub struct NesRecentFilesCapabilities {
621 pub max_count: Option<u32>,
623 #[serde(rename = "_meta")]
629 pub meta: Option<Meta>,
630}
631
632impl NesRecentFilesCapabilities {
633 #[must_use]
635 pub fn new() -> Self {
636 Self::default()
637 }
638}
639
640#[skip_serializing_none]
642#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
643#[serde(rename_all = "camelCase")]
644#[non_exhaustive]
645pub struct NesRelatedSnippetsCapabilities {
646 #[serde(rename = "_meta")]
652 pub meta: Option<Meta>,
653}
654
655impl NesRelatedSnippetsCapabilities {
656 #[must_use]
658 pub fn new() -> Self {
659 Self::default()
660 }
661}
662
663#[skip_serializing_none]
665#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
666#[serde(rename_all = "camelCase")]
667#[non_exhaustive]
668pub struct NesEditHistoryCapabilities {
669 pub max_count: Option<u32>,
671 #[serde(rename = "_meta")]
677 pub meta: Option<Meta>,
678}
679
680impl NesEditHistoryCapabilities {
681 #[must_use]
683 pub fn new() -> Self {
684 Self::default()
685 }
686}
687
688#[skip_serializing_none]
690#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
691#[serde(rename_all = "camelCase")]
692#[non_exhaustive]
693pub struct NesUserActionsCapabilities {
694 pub max_count: Option<u32>,
696 #[serde(rename = "_meta")]
702 pub meta: Option<Meta>,
703}
704
705impl NesUserActionsCapabilities {
706 #[must_use]
708 pub fn new() -> Self {
709 Self::default()
710 }
711}
712
713#[skip_serializing_none]
715#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
716#[serde(rename_all = "camelCase")]
717#[non_exhaustive]
718pub struct NesOpenFilesCapabilities {
719 #[serde(rename = "_meta")]
725 pub meta: Option<Meta>,
726}
727
728impl NesOpenFilesCapabilities {
729 #[must_use]
731 pub fn new() -> Self {
732 Self::default()
733 }
734}
735
736#[skip_serializing_none]
738#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
739#[serde(rename_all = "camelCase")]
740#[non_exhaustive]
741pub struct NesDiagnosticsCapabilities {
742 #[serde(rename = "_meta")]
748 pub meta: Option<Meta>,
749}
750
751impl NesDiagnosticsCapabilities {
752 #[must_use]
754 pub fn new() -> Self {
755 Self::default()
756 }
757}
758
759#[serde_as]
763#[skip_serializing_none]
764#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
765#[serde(rename_all = "camelCase")]
766#[non_exhaustive]
767pub struct ClientNesCapabilities {
768 #[serde_as(deserialize_as = "DefaultOnError")]
770 #[schemars(extend("x-deserialize-default-on-error" = true))]
771 #[serde(default)]
772 pub jump: Option<NesJumpCapabilities>,
773 #[serde_as(deserialize_as = "DefaultOnError")]
775 #[schemars(extend("x-deserialize-default-on-error" = true))]
776 #[serde(default)]
777 pub rename: Option<NesRenameCapabilities>,
778 #[serde_as(deserialize_as = "DefaultOnError")]
780 #[schemars(extend("x-deserialize-default-on-error" = true))]
781 #[serde(default)]
782 pub search_and_replace: Option<NesSearchAndReplaceCapabilities>,
783 #[serde(rename = "_meta")]
789 pub meta: Option<Meta>,
790}
791
792impl ClientNesCapabilities {
793 #[must_use]
795 pub fn new() -> Self {
796 Self::default()
797 }
798
799 #[must_use]
801 pub fn jump(mut self, jump: impl IntoOption<NesJumpCapabilities>) -> Self {
802 self.jump = jump.into_option();
803 self
804 }
805
806 #[must_use]
808 pub fn rename(mut self, rename: impl IntoOption<NesRenameCapabilities>) -> Self {
809 self.rename = rename.into_option();
810 self
811 }
812
813 #[must_use]
815 pub fn search_and_replace(
816 mut self,
817 search_and_replace: impl IntoOption<NesSearchAndReplaceCapabilities>,
818 ) -> Self {
819 self.search_and_replace = search_and_replace.into_option();
820 self
821 }
822
823 #[must_use]
829 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
830 self.meta = meta.into_option();
831 self
832 }
833}
834
835#[skip_serializing_none]
837#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
838#[serde(rename_all = "camelCase")]
839#[non_exhaustive]
840pub struct NesJumpCapabilities {
841 #[serde(rename = "_meta")]
847 pub meta: Option<Meta>,
848}
849
850impl NesJumpCapabilities {
851 #[must_use]
853 pub fn new() -> Self {
854 Self::default()
855 }
856}
857
858#[skip_serializing_none]
860#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
861#[serde(rename_all = "camelCase")]
862#[non_exhaustive]
863pub struct NesRenameCapabilities {
864 #[serde(rename = "_meta")]
870 pub meta: Option<Meta>,
871}
872
873impl NesRenameCapabilities {
874 #[must_use]
876 pub fn new() -> Self {
877 Self::default()
878 }
879}
880
881#[skip_serializing_none]
883#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
884#[serde(rename_all = "camelCase")]
885#[non_exhaustive]
886pub struct NesSearchAndReplaceCapabilities {
887 #[serde(rename = "_meta")]
893 pub meta: Option<Meta>,
894}
895
896impl NesSearchAndReplaceCapabilities {
897 #[must_use]
899 pub fn new() -> Self {
900 Self::default()
901 }
902}
903
904#[skip_serializing_none]
908#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
909#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_OPEN_METHOD_NAME))]
910#[serde(rename_all = "camelCase")]
911#[non_exhaustive]
912pub struct DidOpenDocumentNotification {
913 pub session_id: SessionId,
915 pub uri: String,
917 pub language_id: String,
919 pub version: i64,
921 pub text: String,
923 #[serde(rename = "_meta")]
929 pub meta: Option<Meta>,
930}
931
932impl DidOpenDocumentNotification {
933 #[must_use]
935 pub fn new(
936 session_id: impl Into<SessionId>,
937 uri: impl Into<String>,
938 language_id: impl Into<String>,
939 version: i64,
940 text: impl Into<String>,
941 ) -> Self {
942 Self {
943 session_id: session_id.into(),
944 uri: uri.into(),
945 language_id: language_id.into(),
946 version,
947 text: text.into(),
948 meta: None,
949 }
950 }
951
952 #[must_use]
958 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
959 self.meta = meta.into_option();
960 self
961 }
962}
963
964#[skip_serializing_none]
966#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
967#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_CHANGE_METHOD_NAME))]
968#[serde(rename_all = "camelCase")]
969#[non_exhaustive]
970pub struct DidChangeDocumentNotification {
971 pub session_id: SessionId,
973 pub uri: String,
975 pub version: i64,
977 pub content_changes: Vec<TextDocumentContentChangeEvent>,
979 #[serde(rename = "_meta")]
985 pub meta: Option<Meta>,
986}
987
988impl DidChangeDocumentNotification {
989 #[must_use]
991 pub fn new(
992 session_id: impl Into<SessionId>,
993 uri: impl Into<String>,
994 version: i64,
995 content_changes: Vec<TextDocumentContentChangeEvent>,
996 ) -> Self {
997 Self {
998 session_id: session_id.into(),
999 uri: uri.into(),
1000 version,
1001 content_changes,
1002 meta: None,
1003 }
1004 }
1005
1006 #[must_use]
1012 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1013 self.meta = meta.into_option();
1014 self
1015 }
1016}
1017
1018#[skip_serializing_none]
1023#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1024#[serde(rename_all = "camelCase")]
1025#[non_exhaustive]
1026pub struct TextDocumentContentChangeEvent {
1027 pub range: Option<Range>,
1029 pub text: String,
1031 #[serde(rename = "_meta")]
1037 pub meta: Option<Meta>,
1038}
1039
1040impl TextDocumentContentChangeEvent {
1041 #[must_use]
1043 pub fn full(text: impl Into<String>) -> Self {
1044 Self {
1045 range: None,
1046 text: text.into(),
1047 meta: None,
1048 }
1049 }
1050
1051 #[must_use]
1053 pub fn incremental(range: Range, text: impl Into<String>) -> Self {
1054 Self {
1055 range: Some(range),
1056 text: text.into(),
1057 meta: None,
1058 }
1059 }
1060
1061 #[must_use]
1067 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1068 self.meta = meta.into_option();
1069 self
1070 }
1071}
1072
1073#[skip_serializing_none]
1075#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1076#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_CLOSE_METHOD_NAME))]
1077#[serde(rename_all = "camelCase")]
1078#[non_exhaustive]
1079pub struct DidCloseDocumentNotification {
1080 pub session_id: SessionId,
1082 pub uri: String,
1084 #[serde(rename = "_meta")]
1090 pub meta: Option<Meta>,
1091}
1092
1093impl DidCloseDocumentNotification {
1094 #[must_use]
1096 pub fn new(session_id: impl Into<SessionId>, uri: impl Into<String>) -> Self {
1097 Self {
1098 session_id: session_id.into(),
1099 uri: uri.into(),
1100 meta: None,
1101 }
1102 }
1103
1104 #[must_use]
1110 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1111 self.meta = meta.into_option();
1112 self
1113 }
1114}
1115
1116#[skip_serializing_none]
1118#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1119#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_SAVE_METHOD_NAME))]
1120#[serde(rename_all = "camelCase")]
1121#[non_exhaustive]
1122pub struct DidSaveDocumentNotification {
1123 pub session_id: SessionId,
1125 pub uri: String,
1127 #[serde(rename = "_meta")]
1133 pub meta: Option<Meta>,
1134}
1135
1136impl DidSaveDocumentNotification {
1137 #[must_use]
1139 pub fn new(session_id: impl Into<SessionId>, uri: impl Into<String>) -> Self {
1140 Self {
1141 session_id: session_id.into(),
1142 uri: uri.into(),
1143 meta: None,
1144 }
1145 }
1146
1147 #[must_use]
1153 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1154 self.meta = meta.into_option();
1155 self
1156 }
1157}
1158
1159#[skip_serializing_none]
1161#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1162#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_FOCUS_METHOD_NAME))]
1163#[serde(rename_all = "camelCase")]
1164#[non_exhaustive]
1165pub struct DidFocusDocumentNotification {
1166 pub session_id: SessionId,
1168 pub uri: String,
1170 pub version: i64,
1172 pub position: Position,
1174 pub visible_range: Range,
1176 #[serde(rename = "_meta")]
1182 pub meta: Option<Meta>,
1183}
1184
1185impl DidFocusDocumentNotification {
1186 #[must_use]
1188 pub fn new(
1189 session_id: impl Into<SessionId>,
1190 uri: impl Into<String>,
1191 version: i64,
1192 position: Position,
1193 visible_range: Range,
1194 ) -> Self {
1195 Self {
1196 session_id: session_id.into(),
1197 uri: uri.into(),
1198 version,
1199 position,
1200 visible_range,
1201 meta: None,
1202 }
1203 }
1204
1205 #[must_use]
1211 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1212 self.meta = meta.into_option();
1213 self
1214 }
1215}
1216
1217#[serde_as]
1221#[skip_serializing_none]
1222#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1223#[schemars(extend("x-side" = "agent", "x-method" = NES_START_METHOD_NAME))]
1224#[serde(rename_all = "camelCase")]
1225#[non_exhaustive]
1226pub struct StartNesRequest {
1227 pub workspace_uri: Option<String>,
1229 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1231 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1232 #[serde(default)]
1233 pub workspace_folders: Option<Vec<WorkspaceFolder>>,
1234 #[serde_as(deserialize_as = "DefaultOnError")]
1236 #[schemars(extend("x-deserialize-default-on-error" = true))]
1237 #[serde(default)]
1238 pub repository: Option<NesRepository>,
1239 #[serde(rename = "_meta")]
1245 pub meta: Option<Meta>,
1246}
1247
1248impl StartNesRequest {
1249 #[must_use]
1251 pub fn new() -> Self {
1252 Self {
1253 workspace_uri: None,
1254 workspace_folders: None,
1255 repository: None,
1256 meta: None,
1257 }
1258 }
1259
1260 #[must_use]
1262 pub fn workspace_uri(mut self, workspace_uri: impl IntoOption<String>) -> Self {
1263 self.workspace_uri = workspace_uri.into_option();
1264 self
1265 }
1266
1267 #[must_use]
1269 pub fn workspace_folders(
1270 mut self,
1271 workspace_folders: impl IntoOption<Vec<WorkspaceFolder>>,
1272 ) -> Self {
1273 self.workspace_folders = workspace_folders.into_option();
1274 self
1275 }
1276
1277 #[must_use]
1279 pub fn repository(mut self, repository: impl IntoOption<NesRepository>) -> Self {
1280 self.repository = repository.into_option();
1281 self
1282 }
1283
1284 #[must_use]
1290 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1291 self.meta = meta.into_option();
1292 self
1293 }
1294}
1295
1296impl Default for StartNesRequest {
1297 fn default() -> Self {
1298 Self::new()
1299 }
1300}
1301
1302#[skip_serializing_none]
1304#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1305#[serde(rename_all = "camelCase")]
1306#[non_exhaustive]
1307pub struct WorkspaceFolder {
1308 pub uri: String,
1310 pub name: String,
1312 #[serde(rename = "_meta")]
1318 pub meta: Option<Meta>,
1319}
1320
1321impl WorkspaceFolder {
1322 #[must_use]
1324 pub fn new(uri: impl Into<String>, name: impl Into<String>) -> Self {
1325 Self {
1326 uri: uri.into(),
1327 name: name.into(),
1328 meta: None,
1329 }
1330 }
1331
1332 #[must_use]
1338 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1339 self.meta = meta.into_option();
1340 self
1341 }
1342}
1343
1344#[skip_serializing_none]
1346#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1347#[serde(rename_all = "camelCase")]
1348#[non_exhaustive]
1349pub struct NesRepository {
1350 pub name: String,
1352 pub owner: String,
1354 pub remote_url: String,
1356 #[serde(rename = "_meta")]
1362 pub meta: Option<Meta>,
1363}
1364
1365impl NesRepository {
1366 #[must_use]
1368 pub fn new(
1369 name: impl Into<String>,
1370 owner: impl Into<String>,
1371 remote_url: impl Into<String>,
1372 ) -> Self {
1373 Self {
1374 name: name.into(),
1375 owner: owner.into(),
1376 remote_url: remote_url.into(),
1377 meta: None,
1378 }
1379 }
1380
1381 #[must_use]
1387 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1388 self.meta = meta.into_option();
1389 self
1390 }
1391}
1392
1393#[skip_serializing_none]
1395#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1396#[schemars(extend("x-side" = "agent", "x-method" = NES_START_METHOD_NAME))]
1397#[serde(rename_all = "camelCase")]
1398#[non_exhaustive]
1399pub struct StartNesResponse {
1400 pub session_id: SessionId,
1402 #[serde(rename = "_meta")]
1408 pub meta: Option<Meta>,
1409}
1410
1411impl StartNesResponse {
1412 #[must_use]
1414 pub fn new(session_id: impl Into<SessionId>) -> Self {
1415 Self {
1416 session_id: session_id.into(),
1417 meta: None,
1418 }
1419 }
1420
1421 #[must_use]
1427 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1428 self.meta = meta.into_option();
1429 self
1430 }
1431}
1432
1433#[skip_serializing_none]
1440#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1441#[schemars(extend("x-side" = "agent", "x-method" = NES_CLOSE_METHOD_NAME))]
1442#[serde(rename_all = "camelCase")]
1443#[non_exhaustive]
1444pub struct CloseNesRequest {
1445 pub session_id: SessionId,
1447 #[serde(rename = "_meta")]
1453 pub meta: Option<Meta>,
1454}
1455
1456impl CloseNesRequest {
1457 #[must_use]
1459 pub fn new(session_id: impl Into<SessionId>) -> Self {
1460 Self {
1461 session_id: session_id.into(),
1462 meta: None,
1463 }
1464 }
1465
1466 #[must_use]
1472 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1473 self.meta = meta.into_option();
1474 self
1475 }
1476}
1477
1478#[skip_serializing_none]
1480#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1481#[schemars(extend("x-side" = "agent", "x-method" = NES_CLOSE_METHOD_NAME))]
1482#[serde(rename_all = "camelCase")]
1483#[non_exhaustive]
1484pub struct CloseNesResponse {
1485 #[serde(rename = "_meta")]
1491 pub meta: Option<Meta>,
1492}
1493
1494impl CloseNesResponse {
1495 #[must_use]
1497 pub fn new() -> Self {
1498 Self::default()
1499 }
1500
1501 #[must_use]
1507 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1508 self.meta = meta.into_option();
1509 self
1510 }
1511}
1512
1513#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1517#[non_exhaustive]
1518pub enum NesTriggerKind {
1519 #[serde(rename = "automatic")]
1521 Automatic,
1522 #[serde(rename = "diagnostic")]
1524 Diagnostic,
1525 #[serde(rename = "manual")]
1527 Manual,
1528}
1529
1530#[serde_as]
1532#[skip_serializing_none]
1533#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1534#[schemars(extend("x-side" = "agent", "x-method" = NES_SUGGEST_METHOD_NAME))]
1535#[serde(rename_all = "camelCase")]
1536#[non_exhaustive]
1537pub struct SuggestNesRequest {
1538 pub session_id: SessionId,
1540 pub uri: String,
1542 pub version: i64,
1544 pub position: Position,
1546 #[serde_as(deserialize_as = "DefaultOnError")]
1548 #[schemars(extend("x-deserialize-default-on-error" = true))]
1549 #[serde(default)]
1550 pub selection: Option<Range>,
1551 pub trigger_kind: NesTriggerKind,
1553 #[serde_as(deserialize_as = "DefaultOnError")]
1555 #[schemars(extend("x-deserialize-default-on-error" = true))]
1556 #[serde(default)]
1557 pub context: Option<NesSuggestContext>,
1558 #[serde(rename = "_meta")]
1564 pub meta: Option<Meta>,
1565}
1566
1567impl SuggestNesRequest {
1568 #[must_use]
1570 pub fn new(
1571 session_id: impl Into<SessionId>,
1572 uri: impl Into<String>,
1573 version: i64,
1574 position: Position,
1575 trigger_kind: NesTriggerKind,
1576 ) -> Self {
1577 Self {
1578 session_id: session_id.into(),
1579 uri: uri.into(),
1580 version,
1581 position,
1582 selection: None,
1583 trigger_kind,
1584 context: None,
1585 meta: None,
1586 }
1587 }
1588
1589 #[must_use]
1591 pub fn selection(mut self, selection: impl IntoOption<Range>) -> Self {
1592 self.selection = selection.into_option();
1593 self
1594 }
1595
1596 #[must_use]
1598 pub fn context(mut self, context: impl IntoOption<NesSuggestContext>) -> Self {
1599 self.context = context.into_option();
1600 self
1601 }
1602
1603 #[must_use]
1609 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1610 self.meta = meta.into_option();
1611 self
1612 }
1613}
1614
1615#[serde_as]
1617#[skip_serializing_none]
1618#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1619#[serde(rename_all = "camelCase")]
1620#[non_exhaustive]
1621pub struct NesSuggestContext {
1622 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1624 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1625 #[serde(default)]
1626 pub recent_files: Option<Vec<NesRecentFile>>,
1627 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1629 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1630 #[serde(default)]
1631 pub related_snippets: Option<Vec<NesRelatedSnippet>>,
1632 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1634 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1635 #[serde(default)]
1636 pub edit_history: Option<Vec<NesEditHistoryEntry>>,
1637 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1639 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1640 #[serde(default)]
1641 pub user_actions: Option<Vec<NesUserAction>>,
1642 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1644 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1645 #[serde(default)]
1646 pub open_files: Option<Vec<NesOpenFile>>,
1647 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1649 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1650 #[serde(default)]
1651 pub diagnostics: Option<Vec<NesDiagnostic>>,
1652 #[serde(rename = "_meta")]
1658 pub meta: Option<Meta>,
1659}
1660
1661impl NesSuggestContext {
1662 #[must_use]
1664 pub fn new() -> Self {
1665 Self::default()
1666 }
1667
1668 #[must_use]
1670 pub fn recent_files(mut self, recent_files: impl IntoOption<Vec<NesRecentFile>>) -> Self {
1671 self.recent_files = recent_files.into_option();
1672 self
1673 }
1674
1675 #[must_use]
1677 pub fn related_snippets(
1678 mut self,
1679 related_snippets: impl IntoOption<Vec<NesRelatedSnippet>>,
1680 ) -> Self {
1681 self.related_snippets = related_snippets.into_option();
1682 self
1683 }
1684
1685 #[must_use]
1687 pub fn edit_history(mut self, edit_history: impl IntoOption<Vec<NesEditHistoryEntry>>) -> Self {
1688 self.edit_history = edit_history.into_option();
1689 self
1690 }
1691
1692 #[must_use]
1694 pub fn user_actions(mut self, user_actions: impl IntoOption<Vec<NesUserAction>>) -> Self {
1695 self.user_actions = user_actions.into_option();
1696 self
1697 }
1698
1699 #[must_use]
1701 pub fn open_files(mut self, open_files: impl IntoOption<Vec<NesOpenFile>>) -> Self {
1702 self.open_files = open_files.into_option();
1703 self
1704 }
1705
1706 #[must_use]
1708 pub fn diagnostics(mut self, diagnostics: impl IntoOption<Vec<NesDiagnostic>>) -> Self {
1709 self.diagnostics = diagnostics.into_option();
1710 self
1711 }
1712
1713 #[must_use]
1719 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1720 self.meta = meta.into_option();
1721 self
1722 }
1723}
1724
1725#[skip_serializing_none]
1727#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1728#[serde(rename_all = "camelCase")]
1729#[non_exhaustive]
1730pub struct NesRecentFile {
1731 pub uri: String,
1733 pub language_id: String,
1735 pub text: String,
1737 #[serde(rename = "_meta")]
1743 pub meta: Option<Meta>,
1744}
1745
1746impl NesRecentFile {
1747 #[must_use]
1749 pub fn new(
1750 uri: impl Into<String>,
1751 language_id: impl Into<String>,
1752 text: impl Into<String>,
1753 ) -> Self {
1754 Self {
1755 uri: uri.into(),
1756 language_id: language_id.into(),
1757 text: text.into(),
1758 meta: None,
1759 }
1760 }
1761
1762 #[must_use]
1768 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1769 self.meta = meta.into_option();
1770 self
1771 }
1772}
1773
1774#[skip_serializing_none]
1776#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1777#[serde(rename_all = "camelCase")]
1778#[non_exhaustive]
1779pub struct NesRelatedSnippet {
1780 pub uri: String,
1782 pub excerpts: Vec<NesExcerpt>,
1784 #[serde(rename = "_meta")]
1790 pub meta: Option<Meta>,
1791}
1792
1793impl NesRelatedSnippet {
1794 #[must_use]
1796 pub fn new(uri: impl Into<String>, excerpts: Vec<NesExcerpt>) -> Self {
1797 Self {
1798 uri: uri.into(),
1799 excerpts,
1800 meta: None,
1801 }
1802 }
1803
1804 #[must_use]
1810 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1811 self.meta = meta.into_option();
1812 self
1813 }
1814}
1815
1816#[skip_serializing_none]
1818#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1819#[serde(rename_all = "camelCase")]
1820#[non_exhaustive]
1821pub struct NesExcerpt {
1822 pub start_line: u32,
1824 pub end_line: u32,
1826 pub text: String,
1828 #[serde(rename = "_meta")]
1834 pub meta: Option<Meta>,
1835}
1836
1837impl NesExcerpt {
1838 #[must_use]
1840 pub fn new(start_line: u32, end_line: u32, text: impl Into<String>) -> Self {
1841 Self {
1842 start_line,
1843 end_line,
1844 text: text.into(),
1845 meta: None,
1846 }
1847 }
1848
1849 #[must_use]
1855 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1856 self.meta = meta.into_option();
1857 self
1858 }
1859}
1860
1861#[skip_serializing_none]
1863#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1864#[serde(rename_all = "camelCase")]
1865#[non_exhaustive]
1866pub struct NesEditHistoryEntry {
1867 pub uri: String,
1869 pub diff: String,
1871 #[serde(rename = "_meta")]
1877 pub meta: Option<Meta>,
1878}
1879
1880impl NesEditHistoryEntry {
1881 #[must_use]
1883 pub fn new(uri: impl Into<String>, diff: impl Into<String>) -> Self {
1884 Self {
1885 uri: uri.into(),
1886 diff: diff.into(),
1887 meta: None,
1888 }
1889 }
1890
1891 #[must_use]
1897 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1898 self.meta = meta.into_option();
1899 self
1900 }
1901}
1902
1903#[skip_serializing_none]
1905#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1906#[serde(rename_all = "camelCase")]
1907#[non_exhaustive]
1908pub struct NesUserAction {
1909 pub action: String,
1911 pub uri: String,
1913 pub position: Position,
1915 pub timestamp_ms: u64,
1917 #[serde(rename = "_meta")]
1923 pub meta: Option<Meta>,
1924}
1925
1926impl NesUserAction {
1927 #[must_use]
1929 pub fn new(
1930 action: impl Into<String>,
1931 uri: impl Into<String>,
1932 position: Position,
1933 timestamp_ms: u64,
1934 ) -> Self {
1935 Self {
1936 action: action.into(),
1937 uri: uri.into(),
1938 position,
1939 timestamp_ms,
1940 meta: None,
1941 }
1942 }
1943
1944 #[must_use]
1950 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1951 self.meta = meta.into_option();
1952 self
1953 }
1954}
1955
1956#[serde_as]
1958#[skip_serializing_none]
1959#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1960#[serde(rename_all = "camelCase")]
1961#[non_exhaustive]
1962pub struct NesOpenFile {
1963 pub uri: String,
1965 pub language_id: String,
1967 #[serde_as(deserialize_as = "DefaultOnError")]
1969 #[schemars(extend("x-deserialize-default-on-error" = true))]
1970 #[serde(default)]
1971 pub visible_range: Option<Range>,
1972 #[serde_as(deserialize_as = "DefaultOnError")]
1974 #[schemars(extend("x-deserialize-default-on-error" = true))]
1975 #[serde(default)]
1976 pub last_focused_ms: Option<u64>,
1977 #[serde(rename = "_meta")]
1983 pub meta: Option<Meta>,
1984}
1985
1986impl NesOpenFile {
1987 #[must_use]
1989 pub fn new(uri: impl Into<String>, language_id: impl Into<String>) -> Self {
1990 Self {
1991 uri: uri.into(),
1992 language_id: language_id.into(),
1993 visible_range: None,
1994 last_focused_ms: None,
1995 meta: None,
1996 }
1997 }
1998
1999 #[must_use]
2001 pub fn visible_range(mut self, visible_range: impl IntoOption<Range>) -> Self {
2002 self.visible_range = visible_range.into_option();
2003 self
2004 }
2005
2006 #[must_use]
2008 pub fn last_focused_ms(mut self, last_focused_ms: impl IntoOption<u64>) -> Self {
2009 self.last_focused_ms = last_focused_ms.into_option();
2010 self
2011 }
2012
2013 #[must_use]
2019 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2020 self.meta = meta.into_option();
2021 self
2022 }
2023}
2024
2025#[skip_serializing_none]
2027#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2028#[serde(rename_all = "camelCase")]
2029#[non_exhaustive]
2030pub struct NesDiagnostic {
2031 pub uri: String,
2033 pub range: Range,
2035 pub severity: NesDiagnosticSeverity,
2037 pub message: String,
2039 #[serde(rename = "_meta")]
2045 pub meta: Option<Meta>,
2046}
2047
2048impl NesDiagnostic {
2049 #[must_use]
2051 pub fn new(
2052 uri: impl Into<String>,
2053 range: Range,
2054 severity: NesDiagnosticSeverity,
2055 message: impl Into<String>,
2056 ) -> Self {
2057 Self {
2058 uri: uri.into(),
2059 range,
2060 severity,
2061 message: message.into(),
2062 meta: None,
2063 }
2064 }
2065
2066 #[must_use]
2072 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2073 self.meta = meta.into_option();
2074 self
2075 }
2076}
2077
2078#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2080#[non_exhaustive]
2081pub enum NesDiagnosticSeverity {
2082 #[serde(rename = "error")]
2084 Error,
2085 #[serde(rename = "warning")]
2087 Warning,
2088 #[serde(rename = "information")]
2090 Information,
2091 #[serde(rename = "hint")]
2093 Hint,
2094}
2095
2096#[serde_as]
2100#[skip_serializing_none]
2101#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2102#[schemars(extend("x-side" = "agent", "x-method" = NES_SUGGEST_METHOD_NAME))]
2103#[serde(rename_all = "camelCase")]
2104#[non_exhaustive]
2105pub struct SuggestNesResponse {
2106 #[serde_as(deserialize_as = "DefaultOnError<VecSkipError<_, SkipListener>>")]
2108 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
2109 pub suggestions: Vec<NesSuggestion>,
2110 #[serde(rename = "_meta")]
2116 pub meta: Option<Meta>,
2117}
2118
2119impl SuggestNesResponse {
2120 #[must_use]
2122 pub fn new(suggestions: Vec<NesSuggestion>) -> Self {
2123 Self {
2124 suggestions,
2125 meta: None,
2126 }
2127 }
2128
2129 #[must_use]
2135 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2136 self.meta = meta.into_option();
2137 self
2138 }
2139}
2140
2141#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2143#[serde(tag = "kind", rename_all = "camelCase")]
2144#[schemars(extend("discriminator" = {"propertyName": "kind"}))]
2145#[non_exhaustive]
2146pub enum NesSuggestion {
2147 Edit(NesEditSuggestion),
2149 Jump(NesJumpSuggestion),
2151 Rename(NesRenameSuggestion),
2153 SearchAndReplace(NesSearchAndReplaceSuggestion),
2155}
2156
2157#[serde_as]
2159#[skip_serializing_none]
2160#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2161#[serde(rename_all = "camelCase")]
2162#[non_exhaustive]
2163pub struct NesEditSuggestion {
2164 pub id: String,
2166 pub uri: String,
2168 pub edits: Vec<NesTextEdit>,
2170 #[serde_as(deserialize_as = "DefaultOnError")]
2172 #[schemars(extend("x-deserialize-default-on-error" = true))]
2173 #[serde(default)]
2174 pub cursor_position: Option<Position>,
2175 #[serde(rename = "_meta")]
2181 pub meta: Option<Meta>,
2182}
2183
2184impl NesEditSuggestion {
2185 #[must_use]
2187 pub fn new(id: impl Into<String>, uri: impl Into<String>, edits: Vec<NesTextEdit>) -> Self {
2188 Self {
2189 id: id.into(),
2190 uri: uri.into(),
2191 edits,
2192 cursor_position: None,
2193 meta: None,
2194 }
2195 }
2196
2197 #[must_use]
2199 pub fn cursor_position(mut self, cursor_position: impl IntoOption<Position>) -> Self {
2200 self.cursor_position = cursor_position.into_option();
2201 self
2202 }
2203
2204 #[must_use]
2210 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2211 self.meta = meta.into_option();
2212 self
2213 }
2214}
2215
2216#[skip_serializing_none]
2218#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2219#[serde(rename_all = "camelCase")]
2220#[non_exhaustive]
2221pub struct NesTextEdit {
2222 pub range: Range,
2224 pub new_text: String,
2226 #[serde(rename = "_meta")]
2232 pub meta: Option<Meta>,
2233}
2234
2235impl NesTextEdit {
2236 #[must_use]
2238 pub fn new(range: Range, new_text: impl Into<String>) -> Self {
2239 Self {
2240 range,
2241 new_text: new_text.into(),
2242 meta: None,
2243 }
2244 }
2245
2246 #[must_use]
2252 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2253 self.meta = meta.into_option();
2254 self
2255 }
2256}
2257
2258#[skip_serializing_none]
2260#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2261#[serde(rename_all = "camelCase")]
2262#[non_exhaustive]
2263pub struct NesJumpSuggestion {
2264 pub id: String,
2266 pub uri: String,
2268 pub position: Position,
2270 #[serde(rename = "_meta")]
2276 pub meta: Option<Meta>,
2277}
2278
2279impl NesJumpSuggestion {
2280 #[must_use]
2282 pub fn new(id: impl Into<String>, uri: impl Into<String>, position: Position) -> Self {
2283 Self {
2284 id: id.into(),
2285 uri: uri.into(),
2286 position,
2287 meta: None,
2288 }
2289 }
2290
2291 #[must_use]
2297 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2298 self.meta = meta.into_option();
2299 self
2300 }
2301}
2302
2303#[skip_serializing_none]
2305#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2306#[serde(rename_all = "camelCase")]
2307#[non_exhaustive]
2308pub struct NesRenameSuggestion {
2309 pub id: String,
2311 pub uri: String,
2313 pub position: Position,
2315 pub new_name: String,
2317 #[serde(rename = "_meta")]
2323 pub meta: Option<Meta>,
2324}
2325
2326impl NesRenameSuggestion {
2327 #[must_use]
2329 pub fn new(
2330 id: impl Into<String>,
2331 uri: impl Into<String>,
2332 position: Position,
2333 new_name: impl Into<String>,
2334 ) -> Self {
2335 Self {
2336 id: id.into(),
2337 uri: uri.into(),
2338 position,
2339 new_name: new_name.into(),
2340 meta: None,
2341 }
2342 }
2343
2344 #[must_use]
2350 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2351 self.meta = meta.into_option();
2352 self
2353 }
2354}
2355
2356#[skip_serializing_none]
2358#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2359#[serde(rename_all = "camelCase")]
2360#[non_exhaustive]
2361pub struct NesSearchAndReplaceSuggestion {
2362 pub id: String,
2364 pub uri: String,
2366 pub search: String,
2368 pub replace: String,
2370 pub is_regex: Option<bool>,
2372 #[serde(rename = "_meta")]
2378 pub meta: Option<Meta>,
2379}
2380
2381impl NesSearchAndReplaceSuggestion {
2382 #[must_use]
2384 pub fn new(
2385 id: impl Into<String>,
2386 uri: impl Into<String>,
2387 search: impl Into<String>,
2388 replace: impl Into<String>,
2389 ) -> Self {
2390 Self {
2391 id: id.into(),
2392 uri: uri.into(),
2393 search: search.into(),
2394 replace: replace.into(),
2395 is_regex: None,
2396 meta: None,
2397 }
2398 }
2399
2400 #[must_use]
2402 pub fn is_regex(mut self, is_regex: impl IntoOption<bool>) -> Self {
2403 self.is_regex = is_regex.into_option();
2404 self
2405 }
2406
2407 #[must_use]
2413 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2414 self.meta = meta.into_option();
2415 self
2416 }
2417}
2418
2419#[skip_serializing_none]
2423#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2424#[schemars(extend("x-side" = "agent", "x-method" = NES_ACCEPT_METHOD_NAME))]
2425#[serde(rename_all = "camelCase")]
2426#[non_exhaustive]
2427pub struct AcceptNesNotification {
2428 pub session_id: SessionId,
2430 pub id: String,
2432 #[serde(rename = "_meta")]
2438 pub meta: Option<Meta>,
2439}
2440
2441impl AcceptNesNotification {
2442 #[must_use]
2444 pub fn new(session_id: impl Into<SessionId>, id: impl Into<String>) -> Self {
2445 Self {
2446 session_id: session_id.into(),
2447 id: id.into(),
2448 meta: None,
2449 }
2450 }
2451
2452 #[must_use]
2458 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2459 self.meta = meta.into_option();
2460 self
2461 }
2462}
2463
2464#[serde_as]
2466#[skip_serializing_none]
2467#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2468#[schemars(extend("x-side" = "agent", "x-method" = NES_REJECT_METHOD_NAME))]
2469#[serde(rename_all = "camelCase")]
2470#[non_exhaustive]
2471pub struct RejectNesNotification {
2472 pub session_id: SessionId,
2474 pub id: String,
2476 #[serde_as(deserialize_as = "DefaultOnError")]
2478 #[schemars(extend("x-deserialize-default-on-error" = true))]
2479 #[serde(default)]
2480 pub reason: Option<NesRejectReason>,
2481 #[serde(rename = "_meta")]
2487 pub meta: Option<Meta>,
2488}
2489
2490impl RejectNesNotification {
2491 #[must_use]
2493 pub fn new(session_id: impl Into<SessionId>, id: impl Into<String>) -> Self {
2494 Self {
2495 session_id: session_id.into(),
2496 id: id.into(),
2497 reason: None,
2498 meta: None,
2499 }
2500 }
2501
2502 #[must_use]
2504 pub fn reason(mut self, reason: impl IntoOption<NesRejectReason>) -> Self {
2505 self.reason = reason.into_option();
2506 self
2507 }
2508
2509 #[must_use]
2515 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2516 self.meta = meta.into_option();
2517 self
2518 }
2519}
2520
2521#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2523#[non_exhaustive]
2524pub enum NesRejectReason {
2525 #[serde(rename = "rejected")]
2527 Rejected,
2528 #[serde(rename = "ignored")]
2530 Ignored,
2531 #[serde(rename = "replaced")]
2533 Replaced,
2534 #[serde(rename = "cancelled")]
2536 Cancelled,
2537}
2538
2539#[cfg(test)]
2540mod tests {
2541 use super::*;
2542 use serde_json::json;
2543
2544 #[test]
2545 fn test_position_encoding_kind_serialization() {
2546 assert_eq!(
2547 serde_json::to_value(&PositionEncodingKind::Utf16).unwrap(),
2548 json!("utf-16")
2549 );
2550 assert_eq!(
2551 serde_json::to_value(&PositionEncodingKind::Utf32).unwrap(),
2552 json!("utf-32")
2553 );
2554 assert_eq!(
2555 serde_json::to_value(&PositionEncodingKind::Utf8).unwrap(),
2556 json!("utf-8")
2557 );
2558
2559 assert_eq!(
2560 serde_json::from_value::<PositionEncodingKind>(json!("utf-16")).unwrap(),
2561 PositionEncodingKind::Utf16
2562 );
2563 assert_eq!(
2564 serde_json::from_value::<PositionEncodingKind>(json!("utf-32")).unwrap(),
2565 PositionEncodingKind::Utf32
2566 );
2567 assert_eq!(
2568 serde_json::from_value::<PositionEncodingKind>(json!("utf-8")).unwrap(),
2569 PositionEncodingKind::Utf8
2570 );
2571 }
2572
2573 #[test]
2574 fn test_agent_nes_capabilities_serialization() {
2575 let caps = NesCapabilities::new()
2576 .events(
2577 NesEventCapabilities::new().document(
2578 NesDocumentEventCapabilities::new()
2579 .did_open(NesDocumentDidOpenCapabilities::default())
2580 .did_change(NesDocumentDidChangeCapabilities::new(
2581 TextDocumentSyncKind::Incremental,
2582 ))
2583 .did_close(NesDocumentDidCloseCapabilities::default())
2584 .did_save(NesDocumentDidSaveCapabilities::default())
2585 .did_focus(NesDocumentDidFocusCapabilities::default()),
2586 ),
2587 )
2588 .context(
2589 NesContextCapabilities::new()
2590 .recent_files(NesRecentFilesCapabilities {
2591 max_count: Some(10),
2592 meta: None,
2593 })
2594 .related_snippets(NesRelatedSnippetsCapabilities::default())
2595 .edit_history(NesEditHistoryCapabilities {
2596 max_count: Some(6),
2597 meta: None,
2598 })
2599 .user_actions(NesUserActionsCapabilities {
2600 max_count: Some(16),
2601 meta: None,
2602 })
2603 .open_files(NesOpenFilesCapabilities::default())
2604 .diagnostics(NesDiagnosticsCapabilities::default()),
2605 );
2606
2607 let json = serde_json::to_value(&caps).unwrap();
2608 assert_eq!(
2609 json,
2610 json!({
2611 "events": {
2612 "document": {
2613 "didOpen": {},
2614 "didChange": {
2615 "syncKind": "incremental"
2616 },
2617 "didClose": {},
2618 "didSave": {},
2619 "didFocus": {}
2620 }
2621 },
2622 "context": {
2623 "recentFiles": {
2624 "maxCount": 10
2625 },
2626 "relatedSnippets": {},
2627 "editHistory": {
2628 "maxCount": 6
2629 },
2630 "userActions": {
2631 "maxCount": 16
2632 },
2633 "openFiles": {},
2634 "diagnostics": {}
2635 }
2636 })
2637 );
2638
2639 let deserialized: NesCapabilities = serde_json::from_value(json).unwrap();
2641 assert_eq!(deserialized, caps);
2642 }
2643
2644 #[test]
2645 fn test_client_nes_capabilities_serialization() {
2646 let caps = ClientNesCapabilities::new()
2647 .jump(NesJumpCapabilities::default())
2648 .rename(NesRenameCapabilities::default())
2649 .search_and_replace(NesSearchAndReplaceCapabilities::default());
2650
2651 let json = serde_json::to_value(&caps).unwrap();
2652 assert_eq!(
2653 json,
2654 json!({
2655 "jump": {},
2656 "rename": {},
2657 "searchAndReplace": {}
2658 })
2659 );
2660
2661 let deserialized: ClientNesCapabilities = serde_json::from_value(json).unwrap();
2662 assert_eq!(deserialized, caps);
2663 }
2664
2665 #[test]
2666 fn test_document_did_open_serialization() {
2667 let notification = DidOpenDocumentNotification::new(
2668 "session_123",
2669 "file:///path/to/file.rs",
2670 "rust",
2671 1,
2672 "fn main() {\n println!(\"hello\");\n}\n",
2673 );
2674
2675 let json = serde_json::to_value(¬ification).unwrap();
2676 assert_eq!(
2677 json,
2678 json!({
2679 "sessionId": "session_123",
2680 "uri": "file:///path/to/file.rs",
2681 "languageId": "rust",
2682 "version": 1,
2683 "text": "fn main() {\n println!(\"hello\");\n}\n"
2684 })
2685 );
2686
2687 let deserialized: DidOpenDocumentNotification = serde_json::from_value(json).unwrap();
2688 assert_eq!(deserialized, notification);
2689 }
2690
2691 #[test]
2692 fn test_document_did_change_incremental_serialization() {
2693 let notification = DidChangeDocumentNotification::new(
2694 "session_123",
2695 "file:///path/to/file.rs",
2696 2,
2697 vec![TextDocumentContentChangeEvent::incremental(
2698 Range::new(Position::new(1, 4), Position::new(1, 4)),
2699 "let x = 42;\n ",
2700 )],
2701 );
2702
2703 let json = serde_json::to_value(¬ification).unwrap();
2704 assert_eq!(
2705 json,
2706 json!({
2707 "sessionId": "session_123",
2708 "uri": "file:///path/to/file.rs",
2709 "version": 2,
2710 "contentChanges": [
2711 {
2712 "range": {
2713 "start": { "line": 1, "character": 4 },
2714 "end": { "line": 1, "character": 4 }
2715 },
2716 "text": "let x = 42;\n "
2717 }
2718 ]
2719 })
2720 );
2721 }
2722
2723 #[test]
2724 fn test_document_did_change_full_serialization() {
2725 let notification = DidChangeDocumentNotification::new(
2726 "session_123",
2727 "file:///path/to/file.rs",
2728 2,
2729 vec![TextDocumentContentChangeEvent::full(
2730 "fn main() {\n let x = 42;\n println!(\"hello\");\n}\n",
2731 )],
2732 );
2733
2734 let json = serde_json::to_value(¬ification).unwrap();
2735 assert_eq!(
2736 json,
2737 json!({
2738 "sessionId": "session_123",
2739 "uri": "file:///path/to/file.rs",
2740 "version": 2,
2741 "contentChanges": [
2742 {
2743 "text": "fn main() {\n let x = 42;\n println!(\"hello\");\n}\n"
2744 }
2745 ]
2746 })
2747 );
2748 }
2749
2750 #[test]
2751 fn test_document_did_close_serialization() {
2752 let notification =
2753 DidCloseDocumentNotification::new("session_123", "file:///path/to/file.rs");
2754 let json = serde_json::to_value(¬ification).unwrap();
2755 assert_eq!(
2756 json,
2757 json!({ "sessionId": "session_123", "uri": "file:///path/to/file.rs" })
2758 );
2759 }
2760
2761 #[test]
2762 fn test_document_did_save_serialization() {
2763 let notification =
2764 DidSaveDocumentNotification::new("session_123", "file:///path/to/file.rs");
2765 let json = serde_json::to_value(¬ification).unwrap();
2766 assert_eq!(
2767 json,
2768 json!({ "sessionId": "session_123", "uri": "file:///path/to/file.rs" })
2769 );
2770 }
2771
2772 #[test]
2773 fn test_document_did_focus_serialization() {
2774 let notification = DidFocusDocumentNotification::new(
2775 "session_123",
2776 "file:///path/to/file.rs",
2777 2,
2778 Position::new(5, 12),
2779 Range::new(Position::new(0, 0), Position::new(45, 0)),
2780 );
2781
2782 let json = serde_json::to_value(¬ification).unwrap();
2783 assert_eq!(
2784 json,
2785 json!({
2786 "sessionId": "session_123",
2787 "uri": "file:///path/to/file.rs",
2788 "version": 2,
2789 "position": { "line": 5, "character": 12 },
2790 "visibleRange": {
2791 "start": { "line": 0, "character": 0 },
2792 "end": { "line": 45, "character": 0 }
2793 }
2794 })
2795 );
2796 }
2797
2798 #[test]
2799 fn test_nes_suggestion_edit_serialization() {
2800 let suggestion = NesSuggestion::Edit(
2801 NesEditSuggestion::new(
2802 "sugg_001",
2803 "file:///path/to/other_file.rs",
2804 vec![NesTextEdit::new(
2805 Range::new(Position::new(5, 0), Position::new(5, 10)),
2806 "let result = helper();",
2807 )],
2808 )
2809 .cursor_position(Position::new(5, 22)),
2810 );
2811
2812 let json = serde_json::to_value(&suggestion).unwrap();
2813 assert_eq!(
2814 json,
2815 json!({
2816 "kind": "edit",
2817 "id": "sugg_001",
2818 "uri": "file:///path/to/other_file.rs",
2819 "edits": [
2820 {
2821 "range": {
2822 "start": { "line": 5, "character": 0 },
2823 "end": { "line": 5, "character": 10 }
2824 },
2825 "newText": "let result = helper();"
2826 }
2827 ],
2828 "cursorPosition": { "line": 5, "character": 22 }
2829 })
2830 );
2831
2832 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
2833 assert_eq!(deserialized, suggestion);
2834 }
2835
2836 #[test]
2837 fn test_nes_suggestion_jump_serialization() {
2838 let suggestion = NesSuggestion::Jump(NesJumpSuggestion::new(
2839 "sugg_002",
2840 "file:///path/to/other_file.rs",
2841 Position::new(15, 4),
2842 ));
2843
2844 let json = serde_json::to_value(&suggestion).unwrap();
2845 assert_eq!(
2846 json,
2847 json!({
2848 "kind": "jump",
2849 "id": "sugg_002",
2850 "uri": "file:///path/to/other_file.rs",
2851 "position": { "line": 15, "character": 4 }
2852 })
2853 );
2854
2855 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
2856 assert_eq!(deserialized, suggestion);
2857 }
2858
2859 #[test]
2860 fn test_nes_suggestion_rename_serialization() {
2861 let suggestion = NesSuggestion::Rename(NesRenameSuggestion::new(
2862 "sugg_003",
2863 "file:///path/to/file.rs",
2864 Position::new(5, 10),
2865 "calculateTotal",
2866 ));
2867
2868 let json = serde_json::to_value(&suggestion).unwrap();
2869 assert_eq!(
2870 json,
2871 json!({
2872 "kind": "rename",
2873 "id": "sugg_003",
2874 "uri": "file:///path/to/file.rs",
2875 "position": { "line": 5, "character": 10 },
2876 "newName": "calculateTotal"
2877 })
2878 );
2879
2880 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
2881 assert_eq!(deserialized, suggestion);
2882 }
2883
2884 #[test]
2885 fn test_nes_suggestion_search_and_replace_serialization() {
2886 let suggestion = NesSuggestion::SearchAndReplace(
2887 NesSearchAndReplaceSuggestion::new(
2888 "sugg_004",
2889 "file:///path/to/file.rs",
2890 "oldFunction",
2891 "newFunction",
2892 )
2893 .is_regex(false),
2894 );
2895
2896 let json = serde_json::to_value(&suggestion).unwrap();
2897 assert_eq!(
2898 json,
2899 json!({
2900 "kind": "searchAndReplace",
2901 "id": "sugg_004",
2902 "uri": "file:///path/to/file.rs",
2903 "search": "oldFunction",
2904 "replace": "newFunction",
2905 "isRegex": false
2906 })
2907 );
2908
2909 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
2910 assert_eq!(deserialized, suggestion);
2911 }
2912
2913 #[test]
2914 fn test_nes_start_request_serialization() {
2915 let request = StartNesRequest::new()
2916 .workspace_uri("file:///Users/alice/projects/my-app")
2917 .workspace_folders(vec![WorkspaceFolder::new(
2918 "file:///Users/alice/projects/my-app",
2919 "my-app",
2920 )])
2921 .repository(NesRepository::new(
2922 "my-app",
2923 "alice",
2924 "https://github.com/alice/my-app.git",
2925 ));
2926
2927 let json = serde_json::to_value(&request).unwrap();
2928 assert_eq!(
2929 json,
2930 json!({
2931 "workspaceUri": "file:///Users/alice/projects/my-app",
2932 "workspaceFolders": [
2933 {
2934 "uri": "file:///Users/alice/projects/my-app",
2935 "name": "my-app"
2936 }
2937 ],
2938 "repository": {
2939 "name": "my-app",
2940 "owner": "alice",
2941 "remoteUrl": "https://github.com/alice/my-app.git"
2942 }
2943 })
2944 );
2945 }
2946
2947 #[test]
2948 fn test_nes_start_response_serialization() {
2949 let response = StartNesResponse::new("session_abc123");
2950 let json = serde_json::to_value(&response).unwrap();
2951 assert_eq!(json, json!({ "sessionId": "session_abc123" }));
2952 }
2953
2954 #[test]
2955 fn test_nes_trigger_kind_serialization() {
2956 assert_eq!(
2957 serde_json::to_value(&NesTriggerKind::Automatic).unwrap(),
2958 json!("automatic")
2959 );
2960 assert_eq!(
2961 serde_json::to_value(&NesTriggerKind::Diagnostic).unwrap(),
2962 json!("diagnostic")
2963 );
2964 assert_eq!(
2965 serde_json::to_value(&NesTriggerKind::Manual).unwrap(),
2966 json!("manual")
2967 );
2968 }
2969
2970 #[test]
2971 fn test_nes_reject_reason_serialization() {
2972 assert_eq!(
2973 serde_json::to_value(&NesRejectReason::Rejected).unwrap(),
2974 json!("rejected")
2975 );
2976 assert_eq!(
2977 serde_json::to_value(&NesRejectReason::Ignored).unwrap(),
2978 json!("ignored")
2979 );
2980 assert_eq!(
2981 serde_json::to_value(&NesRejectReason::Replaced).unwrap(),
2982 json!("replaced")
2983 );
2984 assert_eq!(
2985 serde_json::to_value(&NesRejectReason::Cancelled).unwrap(),
2986 json!("cancelled")
2987 );
2988 }
2989
2990 #[test]
2991 fn test_nes_accept_notification_serialization() {
2992 let notification = AcceptNesNotification::new("session_123", "sugg_001");
2993 let json = serde_json::to_value(¬ification).unwrap();
2994 assert_eq!(
2995 json,
2996 json!({ "sessionId": "session_123", "id": "sugg_001" })
2997 );
2998 }
2999
3000 #[test]
3001 fn test_nes_reject_notification_serialization() {
3002 let notification =
3003 RejectNesNotification::new("session_123", "sugg_001").reason(NesRejectReason::Rejected);
3004 let json = serde_json::to_value(¬ification).unwrap();
3005 assert_eq!(
3006 json,
3007 json!({ "sessionId": "session_123", "id": "sugg_001", "reason": "rejected" })
3008 );
3009 }
3010
3011 #[test]
3012 fn test_nes_suggest_request_with_context_serialization() {
3013 let request = SuggestNesRequest::new(
3014 "session_123",
3015 "file:///path/to/file.rs",
3016 2,
3017 Position::new(5, 12),
3018 NesTriggerKind::Automatic,
3019 )
3020 .selection(Range::new(Position::new(5, 4), Position::new(5, 12)))
3021 .context(
3022 NesSuggestContext::new()
3023 .recent_files(vec![NesRecentFile::new(
3024 "file:///path/to/utils.rs",
3025 "rust",
3026 "pub fn helper() -> i32 { 42 }\n",
3027 )])
3028 .diagnostics(vec![NesDiagnostic::new(
3029 "file:///path/to/file.rs",
3030 Range::new(Position::new(5, 0), Position::new(5, 10)),
3031 NesDiagnosticSeverity::Error,
3032 "cannot find value `foo` in this scope",
3033 )]),
3034 );
3035
3036 let json = serde_json::to_value(&request).unwrap();
3037 assert_eq!(json["sessionId"], "session_123");
3038 assert_eq!(json["uri"], "file:///path/to/file.rs");
3039 assert_eq!(json["version"], 2);
3040 assert_eq!(json["triggerKind"], "automatic");
3041 assert_eq!(
3042 json["context"]["recentFiles"][0]["uri"],
3043 "file:///path/to/utils.rs"
3044 );
3045 assert_eq!(json["context"]["diagnostics"][0]["severity"], "error");
3046 }
3047
3048 #[test]
3049 fn test_text_document_sync_kind_serialization() {
3050 assert_eq!(
3051 serde_json::to_value(&TextDocumentSyncKind::Full).unwrap(),
3052 json!("full")
3053 );
3054 assert_eq!(
3055 serde_json::to_value(&TextDocumentSyncKind::Incremental).unwrap(),
3056 json!("incremental")
3057 );
3058 }
3059
3060 #[test]
3061 fn test_document_did_change_capabilities_requires_sync_kind() {
3062 assert!(serde_json::from_value::<NesDocumentDidChangeCapabilities>(json!({})).is_err());
3063 }
3064
3065 #[test]
3066 fn test_nes_suggest_response_serialization() {
3067 let response = SuggestNesResponse::new(vec![
3068 NesSuggestion::Edit(NesEditSuggestion::new(
3069 "sugg_001",
3070 "file:///path/to/file.rs",
3071 vec![NesTextEdit::new(
3072 Range::new(Position::new(5, 0), Position::new(5, 10)),
3073 "let result = helper();",
3074 )],
3075 )),
3076 NesSuggestion::Jump(NesJumpSuggestion::new(
3077 "sugg_002",
3078 "file:///path/to/other.rs",
3079 Position::new(10, 0),
3080 )),
3081 ]);
3082
3083 let json = serde_json::to_value(&response).unwrap();
3084 assert_eq!(json["suggestions"].as_array().unwrap().len(), 2);
3085 assert_eq!(json["suggestions"][0]["kind"], "edit");
3086 assert_eq!(json["suggestions"][1]["kind"], "jump");
3087 }
3088}