1use schemars::JsonSchema;
8use serde::{Deserialize, Serialize};
9use serde_with::{DefaultOnError, VecSkipError, serde_as, skip_serializing_none};
10
11use crate::{IntoOption, SkipListener};
12
13use super::{Meta, SessionId};
14
15pub(crate) const NES_START_METHOD_NAME: &str = "nes/start";
19pub(crate) const NES_SUGGEST_METHOD_NAME: &str = "nes/suggest";
21pub(crate) const NES_ACCEPT_METHOD_NAME: &str = "nes/accept";
23pub(crate) const NES_REJECT_METHOD_NAME: &str = "nes/reject";
25pub(crate) const NES_CLOSE_METHOD_NAME: &str = "nes/close";
27pub(crate) const DOCUMENT_DID_OPEN_METHOD_NAME: &str = "document/didOpen";
29pub(crate) const DOCUMENT_DID_CHANGE_METHOD_NAME: &str = "document/didChange";
31pub(crate) const DOCUMENT_DID_CLOSE_METHOD_NAME: &str = "document/didClose";
33pub(crate) const DOCUMENT_DID_SAVE_METHOD_NAME: &str = "document/didSave";
35pub(crate) const DOCUMENT_DID_FOCUS_METHOD_NAME: &str = "document/didFocus";
37
38#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
44#[non_exhaustive]
45pub enum PositionEncodingKind {
46 #[serde(rename = "utf-16")]
48 Utf16,
49 #[serde(rename = "utf-32")]
51 Utf32,
52 #[serde(rename = "utf-8")]
54 Utf8,
55}
56
57#[skip_serializing_none]
61#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
62#[serde(rename_all = "camelCase")]
63#[non_exhaustive]
64pub struct Position {
65 pub line: u32,
67 pub character: u32,
69 #[serde(rename = "_meta")]
75 pub meta: Option<Meta>,
76}
77
78impl Position {
79 #[must_use]
81 pub fn new(line: u32, character: u32) -> Self {
82 Self {
83 line,
84 character,
85 meta: None,
86 }
87 }
88
89 #[must_use]
95 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
96 self.meta = meta.into_option();
97 self
98 }
99}
100
101#[skip_serializing_none]
103#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
104#[serde(rename_all = "camelCase")]
105#[non_exhaustive]
106pub struct Range {
107 pub start: Position,
109 pub end: Position,
111 #[serde(rename = "_meta")]
117 pub meta: Option<Meta>,
118}
119
120impl Range {
121 #[must_use]
123 pub fn new(start: Position, end: Position) -> Self {
124 Self {
125 start,
126 end,
127 meta: None,
128 }
129 }
130
131 #[must_use]
137 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
138 self.meta = meta.into_option();
139 self
140 }
141}
142
143#[serde_as]
147#[skip_serializing_none]
148#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
149#[serde(rename_all = "camelCase")]
150#[non_exhaustive]
151pub struct NesCapabilities {
152 #[serde_as(deserialize_as = "DefaultOnError")]
154 #[schemars(extend("x-deserialize-default-on-error" = true))]
155 #[serde(default)]
156 pub events: Option<NesEventCapabilities>,
157 #[serde_as(deserialize_as = "DefaultOnError")]
159 #[schemars(extend("x-deserialize-default-on-error" = true))]
160 #[serde(default)]
161 pub context: Option<NesContextCapabilities>,
162 #[serde(rename = "_meta")]
168 pub meta: Option<Meta>,
169}
170
171impl NesCapabilities {
172 #[must_use]
174 pub fn new() -> Self {
175 Self::default()
176 }
177
178 #[must_use]
180 pub fn events(mut self, events: impl IntoOption<NesEventCapabilities>) -> Self {
181 self.events = events.into_option();
182 self
183 }
184
185 #[must_use]
187 pub fn context(mut self, context: impl IntoOption<NesContextCapabilities>) -> Self {
188 self.context = context.into_option();
189 self
190 }
191
192 #[must_use]
198 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
199 self.meta = meta.into_option();
200 self
201 }
202}
203
204#[serde_as]
206#[skip_serializing_none]
207#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
208#[serde(rename_all = "camelCase")]
209#[non_exhaustive]
210pub struct NesEventCapabilities {
211 #[serde_as(deserialize_as = "DefaultOnError")]
213 #[schemars(extend("x-deserialize-default-on-error" = true))]
214 #[serde(default)]
215 pub document: Option<NesDocumentEventCapabilities>,
216 #[serde(rename = "_meta")]
222 pub meta: Option<Meta>,
223}
224
225impl NesEventCapabilities {
226 #[must_use]
228 pub fn new() -> Self {
229 Self::default()
230 }
231
232 #[must_use]
234 pub fn document(mut self, document: impl IntoOption<NesDocumentEventCapabilities>) -> Self {
235 self.document = document.into_option();
236 self
237 }
238
239 #[must_use]
245 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
246 self.meta = meta.into_option();
247 self
248 }
249}
250
251#[serde_as]
253#[skip_serializing_none]
254#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
255#[serde(rename_all = "camelCase")]
256#[non_exhaustive]
257pub struct NesDocumentEventCapabilities {
258 #[serde_as(deserialize_as = "DefaultOnError")]
260 #[schemars(extend("x-deserialize-default-on-error" = true))]
261 #[serde(default)]
262 pub did_open: Option<NesDocumentDidOpenCapabilities>,
263 #[serde_as(deserialize_as = "DefaultOnError")]
265 #[schemars(extend("x-deserialize-default-on-error" = true))]
266 #[serde(default)]
267 pub did_change: Option<NesDocumentDidChangeCapabilities>,
268 #[serde_as(deserialize_as = "DefaultOnError")]
270 #[schemars(extend("x-deserialize-default-on-error" = true))]
271 #[serde(default)]
272 pub did_close: Option<NesDocumentDidCloseCapabilities>,
273 #[serde_as(deserialize_as = "DefaultOnError")]
275 #[schemars(extend("x-deserialize-default-on-error" = true))]
276 #[serde(default)]
277 pub did_save: Option<NesDocumentDidSaveCapabilities>,
278 #[serde_as(deserialize_as = "DefaultOnError")]
280 #[schemars(extend("x-deserialize-default-on-error" = true))]
281 #[serde(default)]
282 pub did_focus: Option<NesDocumentDidFocusCapabilities>,
283 #[serde(rename = "_meta")]
289 pub meta: Option<Meta>,
290}
291
292impl NesDocumentEventCapabilities {
293 #[must_use]
295 pub fn new() -> Self {
296 Self::default()
297 }
298
299 #[must_use]
301 pub fn did_open(mut self, did_open: impl IntoOption<NesDocumentDidOpenCapabilities>) -> Self {
302 self.did_open = did_open.into_option();
303 self
304 }
305
306 #[must_use]
308 pub fn did_change(
309 mut self,
310 did_change: impl IntoOption<NesDocumentDidChangeCapabilities>,
311 ) -> Self {
312 self.did_change = did_change.into_option();
313 self
314 }
315
316 #[must_use]
318 pub fn did_close(
319 mut self,
320 did_close: impl IntoOption<NesDocumentDidCloseCapabilities>,
321 ) -> Self {
322 self.did_close = did_close.into_option();
323 self
324 }
325
326 #[must_use]
328 pub fn did_save(mut self, did_save: impl IntoOption<NesDocumentDidSaveCapabilities>) -> Self {
329 self.did_save = did_save.into_option();
330 self
331 }
332
333 #[must_use]
335 pub fn did_focus(
336 mut self,
337 did_focus: impl IntoOption<NesDocumentDidFocusCapabilities>,
338 ) -> Self {
339 self.did_focus = did_focus.into_option();
340 self
341 }
342
343 #[must_use]
349 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
350 self.meta = meta.into_option();
351 self
352 }
353}
354
355#[skip_serializing_none]
357#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
358#[serde(rename_all = "camelCase")]
359#[non_exhaustive]
360pub struct NesDocumentDidOpenCapabilities {
361 #[serde(rename = "_meta")]
367 pub meta: Option<Meta>,
368}
369
370impl NesDocumentDidOpenCapabilities {
371 #[must_use]
373 pub fn new() -> Self {
374 Self::default()
375 }
376}
377
378#[skip_serializing_none]
380#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
381#[serde(rename_all = "camelCase")]
382#[non_exhaustive]
383pub struct NesDocumentDidChangeCapabilities {
384 pub sync_kind: TextDocumentSyncKind,
386 #[serde(rename = "_meta")]
392 pub meta: Option<Meta>,
393}
394
395impl NesDocumentDidChangeCapabilities {
396 #[must_use]
398 pub fn new(sync_kind: TextDocumentSyncKind) -> Self {
399 Self {
400 sync_kind,
401 meta: None,
402 }
403 }
404
405 #[must_use]
411 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
412 self.meta = meta.into_option();
413 self
414 }
415}
416
417#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
419#[non_exhaustive]
420pub enum TextDocumentSyncKind {
421 #[serde(rename = "full")]
423 Full,
424 #[serde(rename = "incremental")]
426 Incremental,
427}
428
429#[skip_serializing_none]
431#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
432#[serde(rename_all = "camelCase")]
433#[non_exhaustive]
434pub struct NesDocumentDidCloseCapabilities {
435 #[serde(rename = "_meta")]
441 pub meta: Option<Meta>,
442}
443
444impl NesDocumentDidCloseCapabilities {
445 #[must_use]
447 pub fn new() -> Self {
448 Self::default()
449 }
450}
451
452#[skip_serializing_none]
454#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
455#[serde(rename_all = "camelCase")]
456#[non_exhaustive]
457pub struct NesDocumentDidSaveCapabilities {
458 #[serde(rename = "_meta")]
464 pub meta: Option<Meta>,
465}
466
467impl NesDocumentDidSaveCapabilities {
468 #[must_use]
470 pub fn new() -> Self {
471 Self::default()
472 }
473}
474
475#[skip_serializing_none]
477#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
478#[serde(rename_all = "camelCase")]
479#[non_exhaustive]
480pub struct NesDocumentDidFocusCapabilities {
481 #[serde(rename = "_meta")]
487 pub meta: Option<Meta>,
488}
489
490impl NesDocumentDidFocusCapabilities {
491 #[must_use]
493 pub fn new() -> Self {
494 Self::default()
495 }
496}
497
498#[serde_as]
500#[skip_serializing_none]
501#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
502#[serde(rename_all = "camelCase")]
503#[non_exhaustive]
504pub struct NesContextCapabilities {
505 #[serde_as(deserialize_as = "DefaultOnError")]
507 #[schemars(extend("x-deserialize-default-on-error" = true))]
508 #[serde(default)]
509 pub recent_files: Option<NesRecentFilesCapabilities>,
510 #[serde_as(deserialize_as = "DefaultOnError")]
512 #[schemars(extend("x-deserialize-default-on-error" = true))]
513 #[serde(default)]
514 pub related_snippets: Option<NesRelatedSnippetsCapabilities>,
515 #[serde_as(deserialize_as = "DefaultOnError")]
517 #[schemars(extend("x-deserialize-default-on-error" = true))]
518 #[serde(default)]
519 pub edit_history: Option<NesEditHistoryCapabilities>,
520 #[serde_as(deserialize_as = "DefaultOnError")]
522 #[schemars(extend("x-deserialize-default-on-error" = true))]
523 #[serde(default)]
524 pub user_actions: Option<NesUserActionsCapabilities>,
525 #[serde_as(deserialize_as = "DefaultOnError")]
527 #[schemars(extend("x-deserialize-default-on-error" = true))]
528 #[serde(default)]
529 pub open_files: Option<NesOpenFilesCapabilities>,
530 #[serde_as(deserialize_as = "DefaultOnError")]
532 #[schemars(extend("x-deserialize-default-on-error" = true))]
533 #[serde(default)]
534 pub diagnostics: Option<NesDiagnosticsCapabilities>,
535 #[serde(rename = "_meta")]
541 pub meta: Option<Meta>,
542}
543
544impl NesContextCapabilities {
545 #[must_use]
547 pub fn new() -> Self {
548 Self::default()
549 }
550
551 #[must_use]
553 pub fn recent_files(
554 mut self,
555 recent_files: impl IntoOption<NesRecentFilesCapabilities>,
556 ) -> Self {
557 self.recent_files = recent_files.into_option();
558 self
559 }
560
561 #[must_use]
563 pub fn related_snippets(
564 mut self,
565 related_snippets: impl IntoOption<NesRelatedSnippetsCapabilities>,
566 ) -> Self {
567 self.related_snippets = related_snippets.into_option();
568 self
569 }
570
571 #[must_use]
573 pub fn edit_history(
574 mut self,
575 edit_history: impl IntoOption<NesEditHistoryCapabilities>,
576 ) -> Self {
577 self.edit_history = edit_history.into_option();
578 self
579 }
580
581 #[must_use]
583 pub fn user_actions(
584 mut self,
585 user_actions: impl IntoOption<NesUserActionsCapabilities>,
586 ) -> Self {
587 self.user_actions = user_actions.into_option();
588 self
589 }
590
591 #[must_use]
593 pub fn open_files(mut self, open_files: impl IntoOption<NesOpenFilesCapabilities>) -> Self {
594 self.open_files = open_files.into_option();
595 self
596 }
597
598 #[must_use]
600 pub fn diagnostics(mut self, diagnostics: impl IntoOption<NesDiagnosticsCapabilities>) -> Self {
601 self.diagnostics = diagnostics.into_option();
602 self
603 }
604
605 #[must_use]
611 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
612 self.meta = meta.into_option();
613 self
614 }
615}
616
617#[skip_serializing_none]
619#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
620#[serde(rename_all = "camelCase")]
621#[non_exhaustive]
622pub struct NesRecentFilesCapabilities {
623 pub max_count: Option<u32>,
625 #[serde(rename = "_meta")]
631 pub meta: Option<Meta>,
632}
633
634impl NesRecentFilesCapabilities {
635 #[must_use]
637 pub fn new() -> Self {
638 Self::default()
639 }
640}
641
642#[skip_serializing_none]
644#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
645#[serde(rename_all = "camelCase")]
646#[non_exhaustive]
647pub struct NesRelatedSnippetsCapabilities {
648 #[serde(rename = "_meta")]
654 pub meta: Option<Meta>,
655}
656
657impl NesRelatedSnippetsCapabilities {
658 #[must_use]
660 pub fn new() -> Self {
661 Self::default()
662 }
663}
664
665#[skip_serializing_none]
667#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
668#[serde(rename_all = "camelCase")]
669#[non_exhaustive]
670pub struct NesEditHistoryCapabilities {
671 pub max_count: Option<u32>,
673 #[serde(rename = "_meta")]
679 pub meta: Option<Meta>,
680}
681
682impl NesEditHistoryCapabilities {
683 #[must_use]
685 pub fn new() -> Self {
686 Self::default()
687 }
688}
689
690#[skip_serializing_none]
692#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
693#[serde(rename_all = "camelCase")]
694#[non_exhaustive]
695pub struct NesUserActionsCapabilities {
696 pub max_count: Option<u32>,
698 #[serde(rename = "_meta")]
704 pub meta: Option<Meta>,
705}
706
707impl NesUserActionsCapabilities {
708 #[must_use]
710 pub fn new() -> Self {
711 Self::default()
712 }
713}
714
715#[skip_serializing_none]
717#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
718#[serde(rename_all = "camelCase")]
719#[non_exhaustive]
720pub struct NesOpenFilesCapabilities {
721 #[serde(rename = "_meta")]
727 pub meta: Option<Meta>,
728}
729
730impl NesOpenFilesCapabilities {
731 #[must_use]
733 pub fn new() -> Self {
734 Self::default()
735 }
736}
737
738#[skip_serializing_none]
740#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
741#[serde(rename_all = "camelCase")]
742#[non_exhaustive]
743pub struct NesDiagnosticsCapabilities {
744 #[serde(rename = "_meta")]
750 pub meta: Option<Meta>,
751}
752
753impl NesDiagnosticsCapabilities {
754 #[must_use]
756 pub fn new() -> Self {
757 Self::default()
758 }
759}
760
761#[serde_as]
765#[skip_serializing_none]
766#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
767#[serde(rename_all = "camelCase")]
768#[non_exhaustive]
769pub struct ClientNesCapabilities {
770 #[serde_as(deserialize_as = "DefaultOnError")]
772 #[schemars(extend("x-deserialize-default-on-error" = true))]
773 #[serde(default)]
774 pub jump: Option<NesJumpCapabilities>,
775 #[serde_as(deserialize_as = "DefaultOnError")]
777 #[schemars(extend("x-deserialize-default-on-error" = true))]
778 #[serde(default)]
779 pub rename: Option<NesRenameCapabilities>,
780 #[serde_as(deserialize_as = "DefaultOnError")]
782 #[schemars(extend("x-deserialize-default-on-error" = true))]
783 #[serde(default)]
784 pub search_and_replace: Option<NesSearchAndReplaceCapabilities>,
785 #[serde(rename = "_meta")]
791 pub meta: Option<Meta>,
792}
793
794impl ClientNesCapabilities {
795 #[must_use]
797 pub fn new() -> Self {
798 Self::default()
799 }
800
801 #[must_use]
803 pub fn jump(mut self, jump: impl IntoOption<NesJumpCapabilities>) -> Self {
804 self.jump = jump.into_option();
805 self
806 }
807
808 #[must_use]
810 pub fn rename(mut self, rename: impl IntoOption<NesRenameCapabilities>) -> Self {
811 self.rename = rename.into_option();
812 self
813 }
814
815 #[must_use]
817 pub fn search_and_replace(
818 mut self,
819 search_and_replace: impl IntoOption<NesSearchAndReplaceCapabilities>,
820 ) -> Self {
821 self.search_and_replace = search_and_replace.into_option();
822 self
823 }
824
825 #[must_use]
831 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
832 self.meta = meta.into_option();
833 self
834 }
835}
836
837#[skip_serializing_none]
839#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
840#[serde(rename_all = "camelCase")]
841#[non_exhaustive]
842pub struct NesJumpCapabilities {
843 #[serde(rename = "_meta")]
849 pub meta: Option<Meta>,
850}
851
852impl NesJumpCapabilities {
853 #[must_use]
855 pub fn new() -> Self {
856 Self::default()
857 }
858}
859
860#[skip_serializing_none]
862#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
863#[serde(rename_all = "camelCase")]
864#[non_exhaustive]
865pub struct NesRenameCapabilities {
866 #[serde(rename = "_meta")]
872 pub meta: Option<Meta>,
873}
874
875impl NesRenameCapabilities {
876 #[must_use]
878 pub fn new() -> Self {
879 Self::default()
880 }
881}
882
883#[skip_serializing_none]
885#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
886#[serde(rename_all = "camelCase")]
887#[non_exhaustive]
888pub struct NesSearchAndReplaceCapabilities {
889 #[serde(rename = "_meta")]
895 pub meta: Option<Meta>,
896}
897
898impl NesSearchAndReplaceCapabilities {
899 #[must_use]
901 pub fn new() -> Self {
902 Self::default()
903 }
904}
905
906#[skip_serializing_none]
910#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
911#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_OPEN_METHOD_NAME))]
912#[serde(rename_all = "camelCase")]
913#[non_exhaustive]
914pub struct DidOpenDocumentNotification {
915 pub session_id: SessionId,
917 pub uri: String,
919 pub language_id: String,
921 pub version: i64,
923 pub text: String,
925 #[serde(rename = "_meta")]
931 pub meta: Option<Meta>,
932}
933
934impl DidOpenDocumentNotification {
935 #[must_use]
937 pub fn new(
938 session_id: impl Into<SessionId>,
939 uri: impl Into<String>,
940 language_id: impl Into<String>,
941 version: i64,
942 text: impl Into<String>,
943 ) -> Self {
944 Self {
945 session_id: session_id.into(),
946 uri: uri.into(),
947 language_id: language_id.into(),
948 version,
949 text: text.into(),
950 meta: None,
951 }
952 }
953
954 #[must_use]
960 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
961 self.meta = meta.into_option();
962 self
963 }
964}
965
966#[skip_serializing_none]
968#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
969#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_CHANGE_METHOD_NAME))]
970#[serde(rename_all = "camelCase")]
971#[non_exhaustive]
972pub struct DidChangeDocumentNotification {
973 pub session_id: SessionId,
975 pub uri: String,
977 pub version: i64,
979 pub content_changes: Vec<TextDocumentContentChangeEvent>,
981 #[serde(rename = "_meta")]
987 pub meta: Option<Meta>,
988}
989
990impl DidChangeDocumentNotification {
991 #[must_use]
993 pub fn new(
994 session_id: impl Into<SessionId>,
995 uri: impl Into<String>,
996 version: i64,
997 content_changes: Vec<TextDocumentContentChangeEvent>,
998 ) -> Self {
999 Self {
1000 session_id: session_id.into(),
1001 uri: uri.into(),
1002 version,
1003 content_changes,
1004 meta: None,
1005 }
1006 }
1007
1008 #[must_use]
1014 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1015 self.meta = meta.into_option();
1016 self
1017 }
1018}
1019
1020#[skip_serializing_none]
1025#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1026#[serde(rename_all = "camelCase")]
1027#[non_exhaustive]
1028pub struct TextDocumentContentChangeEvent {
1029 pub range: Option<Range>,
1031 pub text: String,
1033 #[serde(rename = "_meta")]
1039 pub meta: Option<Meta>,
1040}
1041
1042impl TextDocumentContentChangeEvent {
1043 #[must_use]
1045 pub fn full(text: impl Into<String>) -> Self {
1046 Self {
1047 range: None,
1048 text: text.into(),
1049 meta: None,
1050 }
1051 }
1052
1053 #[must_use]
1055 pub fn incremental(range: Range, text: impl Into<String>) -> Self {
1056 Self {
1057 range: Some(range),
1058 text: text.into(),
1059 meta: None,
1060 }
1061 }
1062
1063 #[must_use]
1069 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1070 self.meta = meta.into_option();
1071 self
1072 }
1073}
1074
1075#[skip_serializing_none]
1077#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1078#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_CLOSE_METHOD_NAME))]
1079#[serde(rename_all = "camelCase")]
1080#[non_exhaustive]
1081pub struct DidCloseDocumentNotification {
1082 pub session_id: SessionId,
1084 pub uri: String,
1086 #[serde(rename = "_meta")]
1092 pub meta: Option<Meta>,
1093}
1094
1095impl DidCloseDocumentNotification {
1096 #[must_use]
1098 pub fn new(session_id: impl Into<SessionId>, uri: impl Into<String>) -> Self {
1099 Self {
1100 session_id: session_id.into(),
1101 uri: uri.into(),
1102 meta: None,
1103 }
1104 }
1105
1106 #[must_use]
1112 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1113 self.meta = meta.into_option();
1114 self
1115 }
1116}
1117
1118#[skip_serializing_none]
1120#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1121#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_SAVE_METHOD_NAME))]
1122#[serde(rename_all = "camelCase")]
1123#[non_exhaustive]
1124pub struct DidSaveDocumentNotification {
1125 pub session_id: SessionId,
1127 pub uri: String,
1129 #[serde(rename = "_meta")]
1135 pub meta: Option<Meta>,
1136}
1137
1138impl DidSaveDocumentNotification {
1139 #[must_use]
1141 pub fn new(session_id: impl Into<SessionId>, uri: impl Into<String>) -> Self {
1142 Self {
1143 session_id: session_id.into(),
1144 uri: uri.into(),
1145 meta: None,
1146 }
1147 }
1148
1149 #[must_use]
1155 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1156 self.meta = meta.into_option();
1157 self
1158 }
1159}
1160
1161#[skip_serializing_none]
1163#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1164#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_FOCUS_METHOD_NAME))]
1165#[serde(rename_all = "camelCase")]
1166#[non_exhaustive]
1167pub struct DidFocusDocumentNotification {
1168 pub session_id: SessionId,
1170 pub uri: String,
1172 pub version: i64,
1174 pub position: Position,
1176 pub visible_range: Range,
1178 #[serde(rename = "_meta")]
1184 pub meta: Option<Meta>,
1185}
1186
1187impl DidFocusDocumentNotification {
1188 #[must_use]
1190 pub fn new(
1191 session_id: impl Into<SessionId>,
1192 uri: impl Into<String>,
1193 version: i64,
1194 position: Position,
1195 visible_range: Range,
1196 ) -> Self {
1197 Self {
1198 session_id: session_id.into(),
1199 uri: uri.into(),
1200 version,
1201 position,
1202 visible_range,
1203 meta: None,
1204 }
1205 }
1206
1207 #[must_use]
1213 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1214 self.meta = meta.into_option();
1215 self
1216 }
1217}
1218
1219#[serde_as]
1223#[skip_serializing_none]
1224#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1225#[schemars(extend("x-side" = "agent", "x-method" = NES_START_METHOD_NAME))]
1226#[serde(rename_all = "camelCase")]
1227#[non_exhaustive]
1228pub struct StartNesRequest {
1229 pub workspace_uri: Option<String>,
1231 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1233 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1234 #[serde(default)]
1235 pub workspace_folders: Option<Vec<WorkspaceFolder>>,
1236 #[serde_as(deserialize_as = "DefaultOnError")]
1238 #[schemars(extend("x-deserialize-default-on-error" = true))]
1239 #[serde(default)]
1240 pub repository: Option<NesRepository>,
1241 #[serde(rename = "_meta")]
1247 pub meta: Option<Meta>,
1248}
1249
1250impl StartNesRequest {
1251 #[must_use]
1253 pub fn new() -> Self {
1254 Self {
1255 workspace_uri: None,
1256 workspace_folders: None,
1257 repository: None,
1258 meta: None,
1259 }
1260 }
1261
1262 #[must_use]
1264 pub fn workspace_uri(mut self, workspace_uri: impl IntoOption<String>) -> Self {
1265 self.workspace_uri = workspace_uri.into_option();
1266 self
1267 }
1268
1269 #[must_use]
1271 pub fn workspace_folders(
1272 mut self,
1273 workspace_folders: impl IntoOption<Vec<WorkspaceFolder>>,
1274 ) -> Self {
1275 self.workspace_folders = workspace_folders.into_option();
1276 self
1277 }
1278
1279 #[must_use]
1281 pub fn repository(mut self, repository: impl IntoOption<NesRepository>) -> Self {
1282 self.repository = repository.into_option();
1283 self
1284 }
1285
1286 #[must_use]
1292 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1293 self.meta = meta.into_option();
1294 self
1295 }
1296}
1297
1298impl Default for StartNesRequest {
1299 fn default() -> Self {
1300 Self::new()
1301 }
1302}
1303
1304#[skip_serializing_none]
1306#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1307#[serde(rename_all = "camelCase")]
1308#[non_exhaustive]
1309pub struct WorkspaceFolder {
1310 pub uri: String,
1312 pub name: String,
1314 #[serde(rename = "_meta")]
1320 pub meta: Option<Meta>,
1321}
1322
1323impl WorkspaceFolder {
1324 #[must_use]
1326 pub fn new(uri: impl Into<String>, name: impl Into<String>) -> Self {
1327 Self {
1328 uri: uri.into(),
1329 name: name.into(),
1330 meta: None,
1331 }
1332 }
1333
1334 #[must_use]
1340 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1341 self.meta = meta.into_option();
1342 self
1343 }
1344}
1345
1346#[skip_serializing_none]
1348#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1349#[serde(rename_all = "camelCase")]
1350#[non_exhaustive]
1351pub struct NesRepository {
1352 pub name: String,
1354 pub owner: String,
1356 pub remote_url: String,
1358 #[serde(rename = "_meta")]
1364 pub meta: Option<Meta>,
1365}
1366
1367impl NesRepository {
1368 #[must_use]
1370 pub fn new(
1371 name: impl Into<String>,
1372 owner: impl Into<String>,
1373 remote_url: impl Into<String>,
1374 ) -> Self {
1375 Self {
1376 name: name.into(),
1377 owner: owner.into(),
1378 remote_url: remote_url.into(),
1379 meta: None,
1380 }
1381 }
1382
1383 #[must_use]
1389 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1390 self.meta = meta.into_option();
1391 self
1392 }
1393}
1394
1395#[skip_serializing_none]
1397#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1398#[schemars(extend("x-side" = "agent", "x-method" = NES_START_METHOD_NAME))]
1399#[serde(rename_all = "camelCase")]
1400#[non_exhaustive]
1401pub struct StartNesResponse {
1402 pub session_id: SessionId,
1404 #[serde(rename = "_meta")]
1410 pub meta: Option<Meta>,
1411}
1412
1413impl StartNesResponse {
1414 #[must_use]
1416 pub fn new(session_id: impl Into<SessionId>) -> Self {
1417 Self {
1418 session_id: session_id.into(),
1419 meta: None,
1420 }
1421 }
1422
1423 #[must_use]
1429 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1430 self.meta = meta.into_option();
1431 self
1432 }
1433}
1434
1435#[skip_serializing_none]
1442#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1443#[schemars(extend("x-side" = "agent", "x-method" = NES_CLOSE_METHOD_NAME))]
1444#[serde(rename_all = "camelCase")]
1445#[non_exhaustive]
1446pub struct CloseNesRequest {
1447 pub session_id: SessionId,
1449 #[serde(rename = "_meta")]
1455 pub meta: Option<Meta>,
1456}
1457
1458impl CloseNesRequest {
1459 #[must_use]
1461 pub fn new(session_id: impl Into<SessionId>) -> Self {
1462 Self {
1463 session_id: session_id.into(),
1464 meta: None,
1465 }
1466 }
1467
1468 #[must_use]
1474 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1475 self.meta = meta.into_option();
1476 self
1477 }
1478}
1479
1480#[skip_serializing_none]
1482#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1483#[schemars(extend("x-side" = "agent", "x-method" = NES_CLOSE_METHOD_NAME))]
1484#[serde(rename_all = "camelCase")]
1485#[non_exhaustive]
1486pub struct CloseNesResponse {
1487 #[serde(rename = "_meta")]
1493 pub meta: Option<Meta>,
1494}
1495
1496impl CloseNesResponse {
1497 #[must_use]
1499 pub fn new() -> Self {
1500 Self::default()
1501 }
1502
1503 #[must_use]
1509 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1510 self.meta = meta.into_option();
1511 self
1512 }
1513}
1514
1515#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1519#[non_exhaustive]
1520pub enum NesTriggerKind {
1521 #[serde(rename = "automatic")]
1523 Automatic,
1524 #[serde(rename = "diagnostic")]
1526 Diagnostic,
1527 #[serde(rename = "manual")]
1529 Manual,
1530}
1531
1532#[serde_as]
1534#[skip_serializing_none]
1535#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1536#[schemars(extend("x-side" = "agent", "x-method" = NES_SUGGEST_METHOD_NAME))]
1537#[serde(rename_all = "camelCase")]
1538#[non_exhaustive]
1539pub struct SuggestNesRequest {
1540 pub session_id: SessionId,
1542 pub uri: String,
1544 pub version: i64,
1546 pub position: Position,
1548 #[serde_as(deserialize_as = "DefaultOnError")]
1550 #[schemars(extend("x-deserialize-default-on-error" = true))]
1551 #[serde(default)]
1552 pub selection: Option<Range>,
1553 pub trigger_kind: NesTriggerKind,
1555 #[serde_as(deserialize_as = "DefaultOnError")]
1557 #[schemars(extend("x-deserialize-default-on-error" = true))]
1558 #[serde(default)]
1559 pub context: Option<NesSuggestContext>,
1560 #[serde(rename = "_meta")]
1566 pub meta: Option<Meta>,
1567}
1568
1569impl SuggestNesRequest {
1570 #[must_use]
1572 pub fn new(
1573 session_id: impl Into<SessionId>,
1574 uri: impl Into<String>,
1575 version: i64,
1576 position: Position,
1577 trigger_kind: NesTriggerKind,
1578 ) -> Self {
1579 Self {
1580 session_id: session_id.into(),
1581 uri: uri.into(),
1582 version,
1583 position,
1584 selection: None,
1585 trigger_kind,
1586 context: None,
1587 meta: None,
1588 }
1589 }
1590
1591 #[must_use]
1593 pub fn selection(mut self, selection: impl IntoOption<Range>) -> Self {
1594 self.selection = selection.into_option();
1595 self
1596 }
1597
1598 #[must_use]
1600 pub fn context(mut self, context: impl IntoOption<NesSuggestContext>) -> Self {
1601 self.context = context.into_option();
1602 self
1603 }
1604
1605 #[must_use]
1611 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1612 self.meta = meta.into_option();
1613 self
1614 }
1615}
1616
1617#[serde_as]
1619#[skip_serializing_none]
1620#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1621#[serde(rename_all = "camelCase")]
1622#[non_exhaustive]
1623pub struct NesSuggestContext {
1624 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1626 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1627 #[serde(default)]
1628 pub recent_files: Option<Vec<NesRecentFile>>,
1629 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1631 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1632 #[serde(default)]
1633 pub related_snippets: Option<Vec<NesRelatedSnippet>>,
1634 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1636 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1637 #[serde(default)]
1638 pub edit_history: Option<Vec<NesEditHistoryEntry>>,
1639 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1641 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1642 #[serde(default)]
1643 pub user_actions: Option<Vec<NesUserAction>>,
1644 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1646 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1647 #[serde(default)]
1648 pub open_files: Option<Vec<NesOpenFile>>,
1649 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1651 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1652 #[serde(default)]
1653 pub diagnostics: Option<Vec<NesDiagnostic>>,
1654 #[serde(rename = "_meta")]
1660 pub meta: Option<Meta>,
1661}
1662
1663impl NesSuggestContext {
1664 #[must_use]
1666 pub fn new() -> Self {
1667 Self::default()
1668 }
1669
1670 #[must_use]
1672 pub fn recent_files(mut self, recent_files: impl IntoOption<Vec<NesRecentFile>>) -> Self {
1673 self.recent_files = recent_files.into_option();
1674 self
1675 }
1676
1677 #[must_use]
1679 pub fn related_snippets(
1680 mut self,
1681 related_snippets: impl IntoOption<Vec<NesRelatedSnippet>>,
1682 ) -> Self {
1683 self.related_snippets = related_snippets.into_option();
1684 self
1685 }
1686
1687 #[must_use]
1689 pub fn edit_history(mut self, edit_history: impl IntoOption<Vec<NesEditHistoryEntry>>) -> Self {
1690 self.edit_history = edit_history.into_option();
1691 self
1692 }
1693
1694 #[must_use]
1696 pub fn user_actions(mut self, user_actions: impl IntoOption<Vec<NesUserAction>>) -> Self {
1697 self.user_actions = user_actions.into_option();
1698 self
1699 }
1700
1701 #[must_use]
1703 pub fn open_files(mut self, open_files: impl IntoOption<Vec<NesOpenFile>>) -> Self {
1704 self.open_files = open_files.into_option();
1705 self
1706 }
1707
1708 #[must_use]
1710 pub fn diagnostics(mut self, diagnostics: impl IntoOption<Vec<NesDiagnostic>>) -> Self {
1711 self.diagnostics = diagnostics.into_option();
1712 self
1713 }
1714
1715 #[must_use]
1721 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1722 self.meta = meta.into_option();
1723 self
1724 }
1725}
1726
1727#[skip_serializing_none]
1729#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1730#[serde(rename_all = "camelCase")]
1731#[non_exhaustive]
1732pub struct NesRecentFile {
1733 pub uri: String,
1735 pub language_id: String,
1737 pub text: String,
1739 #[serde(rename = "_meta")]
1745 pub meta: Option<Meta>,
1746}
1747
1748impl NesRecentFile {
1749 #[must_use]
1751 pub fn new(
1752 uri: impl Into<String>,
1753 language_id: impl Into<String>,
1754 text: impl Into<String>,
1755 ) -> Self {
1756 Self {
1757 uri: uri.into(),
1758 language_id: language_id.into(),
1759 text: text.into(),
1760 meta: None,
1761 }
1762 }
1763
1764 #[must_use]
1770 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1771 self.meta = meta.into_option();
1772 self
1773 }
1774}
1775
1776#[skip_serializing_none]
1778#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1779#[serde(rename_all = "camelCase")]
1780#[non_exhaustive]
1781pub struct NesRelatedSnippet {
1782 pub uri: String,
1784 pub excerpts: Vec<NesExcerpt>,
1786 #[serde(rename = "_meta")]
1792 pub meta: Option<Meta>,
1793}
1794
1795impl NesRelatedSnippet {
1796 #[must_use]
1798 pub fn new(uri: impl Into<String>, excerpts: Vec<NesExcerpt>) -> Self {
1799 Self {
1800 uri: uri.into(),
1801 excerpts,
1802 meta: None,
1803 }
1804 }
1805
1806 #[must_use]
1812 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1813 self.meta = meta.into_option();
1814 self
1815 }
1816}
1817
1818#[skip_serializing_none]
1820#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1821#[serde(rename_all = "camelCase")]
1822#[non_exhaustive]
1823pub struct NesExcerpt {
1824 pub start_line: u32,
1826 pub end_line: u32,
1828 pub text: String,
1830 #[serde(rename = "_meta")]
1836 pub meta: Option<Meta>,
1837}
1838
1839impl NesExcerpt {
1840 #[must_use]
1842 pub fn new(start_line: u32, end_line: u32, text: impl Into<String>) -> Self {
1843 Self {
1844 start_line,
1845 end_line,
1846 text: text.into(),
1847 meta: None,
1848 }
1849 }
1850
1851 #[must_use]
1857 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1858 self.meta = meta.into_option();
1859 self
1860 }
1861}
1862
1863#[skip_serializing_none]
1865#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1866#[serde(rename_all = "camelCase")]
1867#[non_exhaustive]
1868pub struct NesEditHistoryEntry {
1869 pub uri: String,
1871 pub diff: String,
1873 #[serde(rename = "_meta")]
1879 pub meta: Option<Meta>,
1880}
1881
1882impl NesEditHistoryEntry {
1883 #[must_use]
1885 pub fn new(uri: impl Into<String>, diff: impl Into<String>) -> Self {
1886 Self {
1887 uri: uri.into(),
1888 diff: diff.into(),
1889 meta: None,
1890 }
1891 }
1892
1893 #[must_use]
1899 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1900 self.meta = meta.into_option();
1901 self
1902 }
1903}
1904
1905#[skip_serializing_none]
1907#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1908#[serde(rename_all = "camelCase")]
1909#[non_exhaustive]
1910pub struct NesUserAction {
1911 pub action: String,
1913 pub uri: String,
1915 pub position: Position,
1917 pub timestamp_ms: u64,
1919 #[serde(rename = "_meta")]
1925 pub meta: Option<Meta>,
1926}
1927
1928impl NesUserAction {
1929 #[must_use]
1931 pub fn new(
1932 action: impl Into<String>,
1933 uri: impl Into<String>,
1934 position: Position,
1935 timestamp_ms: u64,
1936 ) -> Self {
1937 Self {
1938 action: action.into(),
1939 uri: uri.into(),
1940 position,
1941 timestamp_ms,
1942 meta: None,
1943 }
1944 }
1945
1946 #[must_use]
1952 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1953 self.meta = meta.into_option();
1954 self
1955 }
1956}
1957
1958#[serde_as]
1960#[skip_serializing_none]
1961#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1962#[serde(rename_all = "camelCase")]
1963#[non_exhaustive]
1964pub struct NesOpenFile {
1965 pub uri: String,
1967 pub language_id: String,
1969 #[serde_as(deserialize_as = "DefaultOnError")]
1971 #[schemars(extend("x-deserialize-default-on-error" = true))]
1972 #[serde(default)]
1973 pub visible_range: Option<Range>,
1974 #[serde_as(deserialize_as = "DefaultOnError")]
1976 #[schemars(extend("x-deserialize-default-on-error" = true))]
1977 #[serde(default)]
1978 pub last_focused_ms: Option<u64>,
1979 #[serde(rename = "_meta")]
1985 pub meta: Option<Meta>,
1986}
1987
1988impl NesOpenFile {
1989 #[must_use]
1991 pub fn new(uri: impl Into<String>, language_id: impl Into<String>) -> Self {
1992 Self {
1993 uri: uri.into(),
1994 language_id: language_id.into(),
1995 visible_range: None,
1996 last_focused_ms: None,
1997 meta: None,
1998 }
1999 }
2000
2001 #[must_use]
2003 pub fn visible_range(mut self, visible_range: impl IntoOption<Range>) -> Self {
2004 self.visible_range = visible_range.into_option();
2005 self
2006 }
2007
2008 #[must_use]
2010 pub fn last_focused_ms(mut self, last_focused_ms: impl IntoOption<u64>) -> Self {
2011 self.last_focused_ms = last_focused_ms.into_option();
2012 self
2013 }
2014
2015 #[must_use]
2021 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2022 self.meta = meta.into_option();
2023 self
2024 }
2025}
2026
2027#[skip_serializing_none]
2029#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2030#[serde(rename_all = "camelCase")]
2031#[non_exhaustive]
2032pub struct NesDiagnostic {
2033 pub uri: String,
2035 pub range: Range,
2037 pub severity: NesDiagnosticSeverity,
2039 pub message: String,
2041 #[serde(rename = "_meta")]
2047 pub meta: Option<Meta>,
2048}
2049
2050impl NesDiagnostic {
2051 #[must_use]
2053 pub fn new(
2054 uri: impl Into<String>,
2055 range: Range,
2056 severity: NesDiagnosticSeverity,
2057 message: impl Into<String>,
2058 ) -> Self {
2059 Self {
2060 uri: uri.into(),
2061 range,
2062 severity,
2063 message: message.into(),
2064 meta: None,
2065 }
2066 }
2067
2068 #[must_use]
2074 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2075 self.meta = meta.into_option();
2076 self
2077 }
2078}
2079
2080#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2082#[non_exhaustive]
2083pub enum NesDiagnosticSeverity {
2084 #[serde(rename = "error")]
2086 Error,
2087 #[serde(rename = "warning")]
2089 Warning,
2090 #[serde(rename = "information")]
2092 Information,
2093 #[serde(rename = "hint")]
2095 Hint,
2096}
2097
2098#[serde_as]
2102#[skip_serializing_none]
2103#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2104#[schemars(extend("x-side" = "agent", "x-method" = NES_SUGGEST_METHOD_NAME))]
2105#[serde(rename_all = "camelCase")]
2106#[non_exhaustive]
2107pub struct SuggestNesResponse {
2108 #[serde_as(deserialize_as = "DefaultOnError<VecSkipError<_, SkipListener>>")]
2110 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
2111 pub suggestions: Vec<NesSuggestion>,
2112 #[serde(rename = "_meta")]
2118 pub meta: Option<Meta>,
2119}
2120
2121impl SuggestNesResponse {
2122 #[must_use]
2124 pub fn new(suggestions: Vec<NesSuggestion>) -> Self {
2125 Self {
2126 suggestions,
2127 meta: None,
2128 }
2129 }
2130
2131 #[must_use]
2137 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2138 self.meta = meta.into_option();
2139 self
2140 }
2141}
2142
2143#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2145#[serde(tag = "kind", rename_all = "camelCase")]
2146#[schemars(extend("discriminator" = {"propertyName": "kind"}))]
2147#[non_exhaustive]
2148pub enum NesSuggestion {
2149 Edit(NesEditSuggestion),
2151 Jump(NesJumpSuggestion),
2153 Rename(NesRenameSuggestion),
2155 SearchAndReplace(NesSearchAndReplaceSuggestion),
2157}
2158
2159#[serde_as]
2161#[skip_serializing_none]
2162#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2163#[serde(rename_all = "camelCase")]
2164#[non_exhaustive]
2165pub struct NesEditSuggestion {
2166 pub id: String,
2168 pub uri: String,
2170 pub edits: Vec<NesTextEdit>,
2172 #[serde_as(deserialize_as = "DefaultOnError")]
2174 #[schemars(extend("x-deserialize-default-on-error" = true))]
2175 #[serde(default)]
2176 pub cursor_position: Option<Position>,
2177 #[serde(rename = "_meta")]
2183 pub meta: Option<Meta>,
2184}
2185
2186impl NesEditSuggestion {
2187 #[must_use]
2189 pub fn new(id: impl Into<String>, uri: impl Into<String>, edits: Vec<NesTextEdit>) -> Self {
2190 Self {
2191 id: id.into(),
2192 uri: uri.into(),
2193 edits,
2194 cursor_position: None,
2195 meta: None,
2196 }
2197 }
2198
2199 #[must_use]
2201 pub fn cursor_position(mut self, cursor_position: impl IntoOption<Position>) -> Self {
2202 self.cursor_position = cursor_position.into_option();
2203 self
2204 }
2205
2206 #[must_use]
2212 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2213 self.meta = meta.into_option();
2214 self
2215 }
2216}
2217
2218#[skip_serializing_none]
2220#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2221#[serde(rename_all = "camelCase")]
2222#[non_exhaustive]
2223pub struct NesTextEdit {
2224 pub range: Range,
2226 pub new_text: String,
2228 #[serde(rename = "_meta")]
2234 pub meta: Option<Meta>,
2235}
2236
2237impl NesTextEdit {
2238 #[must_use]
2240 pub fn new(range: Range, new_text: impl Into<String>) -> Self {
2241 Self {
2242 range,
2243 new_text: new_text.into(),
2244 meta: None,
2245 }
2246 }
2247
2248 #[must_use]
2254 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2255 self.meta = meta.into_option();
2256 self
2257 }
2258}
2259
2260#[skip_serializing_none]
2262#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2263#[serde(rename_all = "camelCase")]
2264#[non_exhaustive]
2265pub struct NesJumpSuggestion {
2266 pub id: String,
2268 pub uri: String,
2270 pub position: Position,
2272 #[serde(rename = "_meta")]
2278 pub meta: Option<Meta>,
2279}
2280
2281impl NesJumpSuggestion {
2282 #[must_use]
2284 pub fn new(id: impl Into<String>, uri: impl Into<String>, position: Position) -> Self {
2285 Self {
2286 id: id.into(),
2287 uri: uri.into(),
2288 position,
2289 meta: None,
2290 }
2291 }
2292
2293 #[must_use]
2299 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2300 self.meta = meta.into_option();
2301 self
2302 }
2303}
2304
2305#[skip_serializing_none]
2307#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2308#[serde(rename_all = "camelCase")]
2309#[non_exhaustive]
2310pub struct NesRenameSuggestion {
2311 pub id: String,
2313 pub uri: String,
2315 pub position: Position,
2317 pub new_name: String,
2319 #[serde(rename = "_meta")]
2325 pub meta: Option<Meta>,
2326}
2327
2328impl NesRenameSuggestion {
2329 #[must_use]
2331 pub fn new(
2332 id: impl Into<String>,
2333 uri: impl Into<String>,
2334 position: Position,
2335 new_name: impl Into<String>,
2336 ) -> Self {
2337 Self {
2338 id: id.into(),
2339 uri: uri.into(),
2340 position,
2341 new_name: new_name.into(),
2342 meta: None,
2343 }
2344 }
2345
2346 #[must_use]
2352 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2353 self.meta = meta.into_option();
2354 self
2355 }
2356}
2357
2358#[skip_serializing_none]
2360#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2361#[serde(rename_all = "camelCase")]
2362#[non_exhaustive]
2363pub struct NesSearchAndReplaceSuggestion {
2364 pub id: String,
2366 pub uri: String,
2368 pub search: String,
2370 pub replace: String,
2372 pub is_regex: Option<bool>,
2374 #[serde(rename = "_meta")]
2380 pub meta: Option<Meta>,
2381}
2382
2383impl NesSearchAndReplaceSuggestion {
2384 #[must_use]
2386 pub fn new(
2387 id: impl Into<String>,
2388 uri: impl Into<String>,
2389 search: impl Into<String>,
2390 replace: impl Into<String>,
2391 ) -> Self {
2392 Self {
2393 id: id.into(),
2394 uri: uri.into(),
2395 search: search.into(),
2396 replace: replace.into(),
2397 is_regex: None,
2398 meta: None,
2399 }
2400 }
2401
2402 #[must_use]
2404 pub fn is_regex(mut self, is_regex: impl IntoOption<bool>) -> Self {
2405 self.is_regex = is_regex.into_option();
2406 self
2407 }
2408
2409 #[must_use]
2415 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2416 self.meta = meta.into_option();
2417 self
2418 }
2419}
2420
2421#[skip_serializing_none]
2425#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2426#[schemars(extend("x-side" = "agent", "x-method" = NES_ACCEPT_METHOD_NAME))]
2427#[serde(rename_all = "camelCase")]
2428#[non_exhaustive]
2429pub struct AcceptNesNotification {
2430 pub session_id: SessionId,
2432 pub id: String,
2434 #[serde(rename = "_meta")]
2440 pub meta: Option<Meta>,
2441}
2442
2443impl AcceptNesNotification {
2444 #[must_use]
2446 pub fn new(session_id: impl Into<SessionId>, id: impl Into<String>) -> Self {
2447 Self {
2448 session_id: session_id.into(),
2449 id: id.into(),
2450 meta: None,
2451 }
2452 }
2453
2454 #[must_use]
2460 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2461 self.meta = meta.into_option();
2462 self
2463 }
2464}
2465
2466#[serde_as]
2468#[skip_serializing_none]
2469#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2470#[schemars(extend("x-side" = "agent", "x-method" = NES_REJECT_METHOD_NAME))]
2471#[serde(rename_all = "camelCase")]
2472#[non_exhaustive]
2473pub struct RejectNesNotification {
2474 pub session_id: SessionId,
2476 pub id: String,
2478 #[serde_as(deserialize_as = "DefaultOnError")]
2480 #[schemars(extend("x-deserialize-default-on-error" = true))]
2481 #[serde(default)]
2482 pub reason: Option<NesRejectReason>,
2483 #[serde(rename = "_meta")]
2489 pub meta: Option<Meta>,
2490}
2491
2492impl RejectNesNotification {
2493 #[must_use]
2495 pub fn new(session_id: impl Into<SessionId>, id: impl Into<String>) -> Self {
2496 Self {
2497 session_id: session_id.into(),
2498 id: id.into(),
2499 reason: None,
2500 meta: None,
2501 }
2502 }
2503
2504 #[must_use]
2506 pub fn reason(mut self, reason: impl IntoOption<NesRejectReason>) -> Self {
2507 self.reason = reason.into_option();
2508 self
2509 }
2510
2511 #[must_use]
2517 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2518 self.meta = meta.into_option();
2519 self
2520 }
2521}
2522
2523#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2525#[non_exhaustive]
2526pub enum NesRejectReason {
2527 #[serde(rename = "rejected")]
2529 Rejected,
2530 #[serde(rename = "ignored")]
2532 Ignored,
2533 #[serde(rename = "replaced")]
2535 Replaced,
2536 #[serde(rename = "cancelled")]
2538 Cancelled,
2539}
2540
2541#[cfg(test)]
2542mod tests {
2543 use super::*;
2544 use serde_json::json;
2545
2546 #[test]
2547 fn test_position_encoding_kind_serialization() {
2548 assert_eq!(
2549 serde_json::to_value(&PositionEncodingKind::Utf16).unwrap(),
2550 json!("utf-16")
2551 );
2552 assert_eq!(
2553 serde_json::to_value(&PositionEncodingKind::Utf32).unwrap(),
2554 json!("utf-32")
2555 );
2556 assert_eq!(
2557 serde_json::to_value(&PositionEncodingKind::Utf8).unwrap(),
2558 json!("utf-8")
2559 );
2560
2561 assert_eq!(
2562 serde_json::from_value::<PositionEncodingKind>(json!("utf-16")).unwrap(),
2563 PositionEncodingKind::Utf16
2564 );
2565 assert_eq!(
2566 serde_json::from_value::<PositionEncodingKind>(json!("utf-32")).unwrap(),
2567 PositionEncodingKind::Utf32
2568 );
2569 assert_eq!(
2570 serde_json::from_value::<PositionEncodingKind>(json!("utf-8")).unwrap(),
2571 PositionEncodingKind::Utf8
2572 );
2573 }
2574
2575 #[test]
2576 fn test_agent_nes_capabilities_serialization() {
2577 let caps = NesCapabilities::new()
2578 .events(
2579 NesEventCapabilities::new().document(
2580 NesDocumentEventCapabilities::new()
2581 .did_open(NesDocumentDidOpenCapabilities::default())
2582 .did_change(NesDocumentDidChangeCapabilities::new(
2583 TextDocumentSyncKind::Incremental,
2584 ))
2585 .did_close(NesDocumentDidCloseCapabilities::default())
2586 .did_save(NesDocumentDidSaveCapabilities::default())
2587 .did_focus(NesDocumentDidFocusCapabilities::default()),
2588 ),
2589 )
2590 .context(
2591 NesContextCapabilities::new()
2592 .recent_files(NesRecentFilesCapabilities {
2593 max_count: Some(10),
2594 meta: None,
2595 })
2596 .related_snippets(NesRelatedSnippetsCapabilities::default())
2597 .edit_history(NesEditHistoryCapabilities {
2598 max_count: Some(6),
2599 meta: None,
2600 })
2601 .user_actions(NesUserActionsCapabilities {
2602 max_count: Some(16),
2603 meta: None,
2604 })
2605 .open_files(NesOpenFilesCapabilities::default())
2606 .diagnostics(NesDiagnosticsCapabilities::default()),
2607 );
2608
2609 let json = serde_json::to_value(&caps).unwrap();
2610 assert_eq!(
2611 json,
2612 json!({
2613 "events": {
2614 "document": {
2615 "didOpen": {},
2616 "didChange": {
2617 "syncKind": "incremental"
2618 },
2619 "didClose": {},
2620 "didSave": {},
2621 "didFocus": {}
2622 }
2623 },
2624 "context": {
2625 "recentFiles": {
2626 "maxCount": 10
2627 },
2628 "relatedSnippets": {},
2629 "editHistory": {
2630 "maxCount": 6
2631 },
2632 "userActions": {
2633 "maxCount": 16
2634 },
2635 "openFiles": {},
2636 "diagnostics": {}
2637 }
2638 })
2639 );
2640
2641 let deserialized: NesCapabilities = serde_json::from_value(json).unwrap();
2643 assert_eq!(deserialized, caps);
2644 }
2645
2646 #[test]
2647 fn test_client_nes_capabilities_serialization() {
2648 let caps = ClientNesCapabilities::new()
2649 .jump(NesJumpCapabilities::default())
2650 .rename(NesRenameCapabilities::default())
2651 .search_and_replace(NesSearchAndReplaceCapabilities::default());
2652
2653 let json = serde_json::to_value(&caps).unwrap();
2654 assert_eq!(
2655 json,
2656 json!({
2657 "jump": {},
2658 "rename": {},
2659 "searchAndReplace": {}
2660 })
2661 );
2662
2663 let deserialized: ClientNesCapabilities = serde_json::from_value(json).unwrap();
2664 assert_eq!(deserialized, caps);
2665 }
2666
2667 #[test]
2668 fn test_document_did_open_serialization() {
2669 let notification = DidOpenDocumentNotification::new(
2670 "session_123",
2671 "file:///path/to/file.rs",
2672 "rust",
2673 1,
2674 "fn main() {\n println!(\"hello\");\n}\n",
2675 );
2676
2677 let json = serde_json::to_value(¬ification).unwrap();
2678 assert_eq!(
2679 json,
2680 json!({
2681 "sessionId": "session_123",
2682 "uri": "file:///path/to/file.rs",
2683 "languageId": "rust",
2684 "version": 1,
2685 "text": "fn main() {\n println!(\"hello\");\n}\n"
2686 })
2687 );
2688
2689 let deserialized: DidOpenDocumentNotification = serde_json::from_value(json).unwrap();
2690 assert_eq!(deserialized, notification);
2691 }
2692
2693 #[test]
2694 fn test_document_did_change_incremental_serialization() {
2695 let notification = DidChangeDocumentNotification::new(
2696 "session_123",
2697 "file:///path/to/file.rs",
2698 2,
2699 vec![TextDocumentContentChangeEvent::incremental(
2700 Range::new(Position::new(1, 4), Position::new(1, 4)),
2701 "let x = 42;\n ",
2702 )],
2703 );
2704
2705 let json = serde_json::to_value(¬ification).unwrap();
2706 assert_eq!(
2707 json,
2708 json!({
2709 "sessionId": "session_123",
2710 "uri": "file:///path/to/file.rs",
2711 "version": 2,
2712 "contentChanges": [
2713 {
2714 "range": {
2715 "start": { "line": 1, "character": 4 },
2716 "end": { "line": 1, "character": 4 }
2717 },
2718 "text": "let x = 42;\n "
2719 }
2720 ]
2721 })
2722 );
2723 }
2724
2725 #[test]
2726 fn test_document_did_change_full_serialization() {
2727 let notification = DidChangeDocumentNotification::new(
2728 "session_123",
2729 "file:///path/to/file.rs",
2730 2,
2731 vec![TextDocumentContentChangeEvent::full(
2732 "fn main() {\n let x = 42;\n println!(\"hello\");\n}\n",
2733 )],
2734 );
2735
2736 let json = serde_json::to_value(¬ification).unwrap();
2737 assert_eq!(
2738 json,
2739 json!({
2740 "sessionId": "session_123",
2741 "uri": "file:///path/to/file.rs",
2742 "version": 2,
2743 "contentChanges": [
2744 {
2745 "text": "fn main() {\n let x = 42;\n println!(\"hello\");\n}\n"
2746 }
2747 ]
2748 })
2749 );
2750 }
2751
2752 #[test]
2753 fn test_document_did_close_serialization() {
2754 let notification =
2755 DidCloseDocumentNotification::new("session_123", "file:///path/to/file.rs");
2756 let json = serde_json::to_value(¬ification).unwrap();
2757 assert_eq!(
2758 json,
2759 json!({ "sessionId": "session_123", "uri": "file:///path/to/file.rs" })
2760 );
2761 }
2762
2763 #[test]
2764 fn test_document_did_save_serialization() {
2765 let notification =
2766 DidSaveDocumentNotification::new("session_123", "file:///path/to/file.rs");
2767 let json = serde_json::to_value(¬ification).unwrap();
2768 assert_eq!(
2769 json,
2770 json!({ "sessionId": "session_123", "uri": "file:///path/to/file.rs" })
2771 );
2772 }
2773
2774 #[test]
2775 fn test_document_did_focus_serialization() {
2776 let notification = DidFocusDocumentNotification::new(
2777 "session_123",
2778 "file:///path/to/file.rs",
2779 2,
2780 Position::new(5, 12),
2781 Range::new(Position::new(0, 0), Position::new(45, 0)),
2782 );
2783
2784 let json = serde_json::to_value(¬ification).unwrap();
2785 assert_eq!(
2786 json,
2787 json!({
2788 "sessionId": "session_123",
2789 "uri": "file:///path/to/file.rs",
2790 "version": 2,
2791 "position": { "line": 5, "character": 12 },
2792 "visibleRange": {
2793 "start": { "line": 0, "character": 0 },
2794 "end": { "line": 45, "character": 0 }
2795 }
2796 })
2797 );
2798 }
2799
2800 #[test]
2801 fn test_nes_suggestion_edit_serialization() {
2802 let suggestion = NesSuggestion::Edit(
2803 NesEditSuggestion::new(
2804 "sugg_001",
2805 "file:///path/to/other_file.rs",
2806 vec![NesTextEdit::new(
2807 Range::new(Position::new(5, 0), Position::new(5, 10)),
2808 "let result = helper();",
2809 )],
2810 )
2811 .cursor_position(Position::new(5, 22)),
2812 );
2813
2814 let json = serde_json::to_value(&suggestion).unwrap();
2815 assert_eq!(
2816 json,
2817 json!({
2818 "kind": "edit",
2819 "id": "sugg_001",
2820 "uri": "file:///path/to/other_file.rs",
2821 "edits": [
2822 {
2823 "range": {
2824 "start": { "line": 5, "character": 0 },
2825 "end": { "line": 5, "character": 10 }
2826 },
2827 "newText": "let result = helper();"
2828 }
2829 ],
2830 "cursorPosition": { "line": 5, "character": 22 }
2831 })
2832 );
2833
2834 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
2835 assert_eq!(deserialized, suggestion);
2836 }
2837
2838 #[test]
2839 fn test_nes_suggestion_jump_serialization() {
2840 let suggestion = NesSuggestion::Jump(NesJumpSuggestion::new(
2841 "sugg_002",
2842 "file:///path/to/other_file.rs",
2843 Position::new(15, 4),
2844 ));
2845
2846 let json = serde_json::to_value(&suggestion).unwrap();
2847 assert_eq!(
2848 json,
2849 json!({
2850 "kind": "jump",
2851 "id": "sugg_002",
2852 "uri": "file:///path/to/other_file.rs",
2853 "position": { "line": 15, "character": 4 }
2854 })
2855 );
2856
2857 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
2858 assert_eq!(deserialized, suggestion);
2859 }
2860
2861 #[test]
2862 fn test_nes_suggestion_rename_serialization() {
2863 let suggestion = NesSuggestion::Rename(NesRenameSuggestion::new(
2864 "sugg_003",
2865 "file:///path/to/file.rs",
2866 Position::new(5, 10),
2867 "calculateTotal",
2868 ));
2869
2870 let json = serde_json::to_value(&suggestion).unwrap();
2871 assert_eq!(
2872 json,
2873 json!({
2874 "kind": "rename",
2875 "id": "sugg_003",
2876 "uri": "file:///path/to/file.rs",
2877 "position": { "line": 5, "character": 10 },
2878 "newName": "calculateTotal"
2879 })
2880 );
2881
2882 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
2883 assert_eq!(deserialized, suggestion);
2884 }
2885
2886 #[test]
2887 fn test_nes_suggestion_search_and_replace_serialization() {
2888 let suggestion = NesSuggestion::SearchAndReplace(
2889 NesSearchAndReplaceSuggestion::new(
2890 "sugg_004",
2891 "file:///path/to/file.rs",
2892 "oldFunction",
2893 "newFunction",
2894 )
2895 .is_regex(false),
2896 );
2897
2898 let json = serde_json::to_value(&suggestion).unwrap();
2899 assert_eq!(
2900 json,
2901 json!({
2902 "kind": "searchAndReplace",
2903 "id": "sugg_004",
2904 "uri": "file:///path/to/file.rs",
2905 "search": "oldFunction",
2906 "replace": "newFunction",
2907 "isRegex": false
2908 })
2909 );
2910
2911 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
2912 assert_eq!(deserialized, suggestion);
2913 }
2914
2915 #[test]
2916 fn test_nes_start_request_serialization() {
2917 let request = StartNesRequest::new()
2918 .workspace_uri("file:///Users/alice/projects/my-app")
2919 .workspace_folders(vec![WorkspaceFolder::new(
2920 "file:///Users/alice/projects/my-app",
2921 "my-app",
2922 )])
2923 .repository(NesRepository::new(
2924 "my-app",
2925 "alice",
2926 "https://github.com/alice/my-app.git",
2927 ));
2928
2929 let json = serde_json::to_value(&request).unwrap();
2930 assert_eq!(
2931 json,
2932 json!({
2933 "workspaceUri": "file:///Users/alice/projects/my-app",
2934 "workspaceFolders": [
2935 {
2936 "uri": "file:///Users/alice/projects/my-app",
2937 "name": "my-app"
2938 }
2939 ],
2940 "repository": {
2941 "name": "my-app",
2942 "owner": "alice",
2943 "remoteUrl": "https://github.com/alice/my-app.git"
2944 }
2945 })
2946 );
2947 }
2948
2949 #[test]
2950 fn test_nes_start_response_serialization() {
2951 let response = StartNesResponse::new("session_abc123");
2952 let json = serde_json::to_value(&response).unwrap();
2953 assert_eq!(json, json!({ "sessionId": "session_abc123" }));
2954 }
2955
2956 #[test]
2957 fn test_nes_trigger_kind_serialization() {
2958 assert_eq!(
2959 serde_json::to_value(&NesTriggerKind::Automatic).unwrap(),
2960 json!("automatic")
2961 );
2962 assert_eq!(
2963 serde_json::to_value(&NesTriggerKind::Diagnostic).unwrap(),
2964 json!("diagnostic")
2965 );
2966 assert_eq!(
2967 serde_json::to_value(&NesTriggerKind::Manual).unwrap(),
2968 json!("manual")
2969 );
2970 }
2971
2972 #[test]
2973 fn test_nes_reject_reason_serialization() {
2974 assert_eq!(
2975 serde_json::to_value(&NesRejectReason::Rejected).unwrap(),
2976 json!("rejected")
2977 );
2978 assert_eq!(
2979 serde_json::to_value(&NesRejectReason::Ignored).unwrap(),
2980 json!("ignored")
2981 );
2982 assert_eq!(
2983 serde_json::to_value(&NesRejectReason::Replaced).unwrap(),
2984 json!("replaced")
2985 );
2986 assert_eq!(
2987 serde_json::to_value(&NesRejectReason::Cancelled).unwrap(),
2988 json!("cancelled")
2989 );
2990 }
2991
2992 #[test]
2993 fn test_nes_accept_notification_serialization() {
2994 let notification = AcceptNesNotification::new("session_123", "sugg_001");
2995 let json = serde_json::to_value(¬ification).unwrap();
2996 assert_eq!(
2997 json,
2998 json!({ "sessionId": "session_123", "id": "sugg_001" })
2999 );
3000 }
3001
3002 #[test]
3003 fn test_nes_reject_notification_serialization() {
3004 let notification =
3005 RejectNesNotification::new("session_123", "sugg_001").reason(NesRejectReason::Rejected);
3006 let json = serde_json::to_value(¬ification).unwrap();
3007 assert_eq!(
3008 json,
3009 json!({ "sessionId": "session_123", "id": "sugg_001", "reason": "rejected" })
3010 );
3011 }
3012
3013 #[test]
3014 fn test_nes_suggest_request_with_context_serialization() {
3015 let request = SuggestNesRequest::new(
3016 "session_123",
3017 "file:///path/to/file.rs",
3018 2,
3019 Position::new(5, 12),
3020 NesTriggerKind::Automatic,
3021 )
3022 .selection(Range::new(Position::new(5, 4), Position::new(5, 12)))
3023 .context(
3024 NesSuggestContext::new()
3025 .recent_files(vec![NesRecentFile::new(
3026 "file:///path/to/utils.rs",
3027 "rust",
3028 "pub fn helper() -> i32 { 42 }\n",
3029 )])
3030 .diagnostics(vec![NesDiagnostic::new(
3031 "file:///path/to/file.rs",
3032 Range::new(Position::new(5, 0), Position::new(5, 10)),
3033 NesDiagnosticSeverity::Error,
3034 "cannot find value `foo` in this scope",
3035 )]),
3036 );
3037
3038 let json = serde_json::to_value(&request).unwrap();
3039 assert_eq!(json["sessionId"], "session_123");
3040 assert_eq!(json["uri"], "file:///path/to/file.rs");
3041 assert_eq!(json["version"], 2);
3042 assert_eq!(json["triggerKind"], "automatic");
3043 assert_eq!(
3044 json["context"]["recentFiles"][0]["uri"],
3045 "file:///path/to/utils.rs"
3046 );
3047 assert_eq!(json["context"]["diagnostics"][0]["severity"], "error");
3048 }
3049
3050 #[test]
3051 fn test_text_document_sync_kind_serialization() {
3052 assert_eq!(
3053 serde_json::to_value(&TextDocumentSyncKind::Full).unwrap(),
3054 json!("full")
3055 );
3056 assert_eq!(
3057 serde_json::to_value(&TextDocumentSyncKind::Incremental).unwrap(),
3058 json!("incremental")
3059 );
3060 }
3061
3062 #[test]
3063 fn test_document_did_change_capabilities_requires_sync_kind() {
3064 assert!(serde_json::from_value::<NesDocumentDidChangeCapabilities>(json!({})).is_err());
3065 }
3066
3067 #[test]
3068 fn test_nes_suggest_response_serialization() {
3069 let response = SuggestNesResponse::new(vec![
3070 NesSuggestion::Edit(NesEditSuggestion::new(
3071 "sugg_001",
3072 "file:///path/to/file.rs",
3073 vec![NesTextEdit::new(
3074 Range::new(Position::new(5, 0), Position::new(5, 10)),
3075 "let result = helper();",
3076 )],
3077 )),
3078 NesSuggestion::Jump(NesJumpSuggestion::new(
3079 "sugg_002",
3080 "file:///path/to/other.rs",
3081 Position::new(10, 0),
3082 )),
3083 ]);
3084
3085 let json = serde_json::to_value(&response).unwrap();
3086 assert_eq!(json["suggestions"].as_array().unwrap().len(), 2);
3087 assert_eq!(json["suggestions"][0]["kind"], "edit");
3088 assert_eq!(json["suggestions"][1]["kind"], "jump");
3089 }
3090}