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]
78 pub fn new(line: u32, character: u32) -> Self {
79 Self {
80 line,
81 character,
82 meta: None,
83 }
84 }
85
86 #[must_use]
92 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
93 self.meta = meta.into_option();
94 self
95 }
96}
97
98#[skip_serializing_none]
100#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
101#[serde(rename_all = "camelCase")]
102#[non_exhaustive]
103pub struct Range {
104 pub start: Position,
106 pub end: Position,
108 #[serde(rename = "_meta")]
114 pub meta: Option<Meta>,
115}
116
117impl Range {
118 #[must_use]
119 pub fn new(start: Position, end: Position) -> Self {
120 Self {
121 start,
122 end,
123 meta: None,
124 }
125 }
126
127 #[must_use]
133 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
134 self.meta = meta.into_option();
135 self
136 }
137}
138
139#[serde_as]
143#[skip_serializing_none]
144#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
145#[serde(rename_all = "camelCase")]
146#[non_exhaustive]
147pub struct NesCapabilities {
148 #[serde_as(deserialize_as = "DefaultOnError")]
150 #[schemars(extend("x-deserialize-default-on-error" = true))]
151 #[serde(default)]
152 pub events: Option<NesEventCapabilities>,
153 #[serde_as(deserialize_as = "DefaultOnError")]
155 #[schemars(extend("x-deserialize-default-on-error" = true))]
156 #[serde(default)]
157 pub context: Option<NesContextCapabilities>,
158 #[serde(rename = "_meta")]
164 pub meta: Option<Meta>,
165}
166
167impl NesCapabilities {
168 #[must_use]
169 pub fn new() -> Self {
170 Self::default()
171 }
172
173 #[must_use]
174 pub fn events(mut self, events: impl IntoOption<NesEventCapabilities>) -> Self {
175 self.events = events.into_option();
176 self
177 }
178
179 #[must_use]
180 pub fn context(mut self, context: impl IntoOption<NesContextCapabilities>) -> Self {
181 self.context = context.into_option();
182 self
183 }
184
185 #[must_use]
191 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
192 self.meta = meta.into_option();
193 self
194 }
195}
196
197#[serde_as]
199#[skip_serializing_none]
200#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
201#[serde(rename_all = "camelCase")]
202#[non_exhaustive]
203pub struct NesEventCapabilities {
204 #[serde_as(deserialize_as = "DefaultOnError")]
206 #[schemars(extend("x-deserialize-default-on-error" = true))]
207 #[serde(default)]
208 pub document: Option<NesDocumentEventCapabilities>,
209 #[serde(rename = "_meta")]
215 pub meta: Option<Meta>,
216}
217
218impl NesEventCapabilities {
219 #[must_use]
220 pub fn new() -> Self {
221 Self::default()
222 }
223
224 #[must_use]
225 pub fn document(mut self, document: impl IntoOption<NesDocumentEventCapabilities>) -> Self {
226 self.document = document.into_option();
227 self
228 }
229
230 #[must_use]
236 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
237 self.meta = meta.into_option();
238 self
239 }
240}
241
242#[serde_as]
244#[skip_serializing_none]
245#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
246#[serde(rename_all = "camelCase")]
247#[non_exhaustive]
248pub struct NesDocumentEventCapabilities {
249 #[serde_as(deserialize_as = "DefaultOnError")]
251 #[schemars(extend("x-deserialize-default-on-error" = true))]
252 #[serde(default)]
253 pub did_open: Option<NesDocumentDidOpenCapabilities>,
254 #[serde_as(deserialize_as = "DefaultOnError")]
256 #[schemars(extend("x-deserialize-default-on-error" = true))]
257 #[serde(default)]
258 pub did_change: Option<NesDocumentDidChangeCapabilities>,
259 #[serde_as(deserialize_as = "DefaultOnError")]
261 #[schemars(extend("x-deserialize-default-on-error" = true))]
262 #[serde(default)]
263 pub did_close: Option<NesDocumentDidCloseCapabilities>,
264 #[serde_as(deserialize_as = "DefaultOnError")]
266 #[schemars(extend("x-deserialize-default-on-error" = true))]
267 #[serde(default)]
268 pub did_save: Option<NesDocumentDidSaveCapabilities>,
269 #[serde_as(deserialize_as = "DefaultOnError")]
271 #[schemars(extend("x-deserialize-default-on-error" = true))]
272 #[serde(default)]
273 pub did_focus: Option<NesDocumentDidFocusCapabilities>,
274 #[serde(rename = "_meta")]
280 pub meta: Option<Meta>,
281}
282
283impl NesDocumentEventCapabilities {
284 #[must_use]
285 pub fn new() -> Self {
286 Self::default()
287 }
288
289 #[must_use]
290 pub fn did_open(mut self, did_open: impl IntoOption<NesDocumentDidOpenCapabilities>) -> Self {
291 self.did_open = did_open.into_option();
292 self
293 }
294
295 #[must_use]
296 pub fn did_change(
297 mut self,
298 did_change: impl IntoOption<NesDocumentDidChangeCapabilities>,
299 ) -> Self {
300 self.did_change = did_change.into_option();
301 self
302 }
303
304 #[must_use]
305 pub fn did_close(
306 mut self,
307 did_close: impl IntoOption<NesDocumentDidCloseCapabilities>,
308 ) -> Self {
309 self.did_close = did_close.into_option();
310 self
311 }
312
313 #[must_use]
314 pub fn did_save(mut self, did_save: impl IntoOption<NesDocumentDidSaveCapabilities>) -> Self {
315 self.did_save = did_save.into_option();
316 self
317 }
318
319 #[must_use]
320 pub fn did_focus(
321 mut self,
322 did_focus: impl IntoOption<NesDocumentDidFocusCapabilities>,
323 ) -> Self {
324 self.did_focus = did_focus.into_option();
325 self
326 }
327
328 #[must_use]
334 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
335 self.meta = meta.into_option();
336 self
337 }
338}
339
340#[skip_serializing_none]
342#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
343#[serde(rename_all = "camelCase")]
344#[non_exhaustive]
345pub struct NesDocumentDidOpenCapabilities {
346 #[serde(rename = "_meta")]
352 pub meta: Option<Meta>,
353}
354
355impl NesDocumentDidOpenCapabilities {
356 #[must_use]
357 pub fn new() -> Self {
358 Self::default()
359 }
360}
361
362#[skip_serializing_none]
364#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
365#[serde(rename_all = "camelCase")]
366#[non_exhaustive]
367pub struct NesDocumentDidChangeCapabilities {
368 pub sync_kind: TextDocumentSyncKind,
370 #[serde(rename = "_meta")]
376 pub meta: Option<Meta>,
377}
378
379impl NesDocumentDidChangeCapabilities {
380 #[must_use]
381 pub fn new(sync_kind: TextDocumentSyncKind) -> Self {
382 Self {
383 sync_kind,
384 meta: None,
385 }
386 }
387
388 #[must_use]
394 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
395 self.meta = meta.into_option();
396 self
397 }
398}
399
400#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
402#[non_exhaustive]
403pub enum TextDocumentSyncKind {
404 #[serde(rename = "full")]
406 Full,
407 #[serde(rename = "incremental")]
409 Incremental,
410}
411
412#[skip_serializing_none]
414#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
415#[serde(rename_all = "camelCase")]
416#[non_exhaustive]
417pub struct NesDocumentDidCloseCapabilities {
418 #[serde(rename = "_meta")]
424 pub meta: Option<Meta>,
425}
426
427impl NesDocumentDidCloseCapabilities {
428 #[must_use]
429 pub fn new() -> Self {
430 Self::default()
431 }
432}
433
434#[skip_serializing_none]
436#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
437#[serde(rename_all = "camelCase")]
438#[non_exhaustive]
439pub struct NesDocumentDidSaveCapabilities {
440 #[serde(rename = "_meta")]
446 pub meta: Option<Meta>,
447}
448
449impl NesDocumentDidSaveCapabilities {
450 #[must_use]
451 pub fn new() -> Self {
452 Self::default()
453 }
454}
455
456#[skip_serializing_none]
458#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
459#[serde(rename_all = "camelCase")]
460#[non_exhaustive]
461pub struct NesDocumentDidFocusCapabilities {
462 #[serde(rename = "_meta")]
468 pub meta: Option<Meta>,
469}
470
471impl NesDocumentDidFocusCapabilities {
472 #[must_use]
473 pub fn new() -> Self {
474 Self::default()
475 }
476}
477
478#[serde_as]
480#[skip_serializing_none]
481#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
482#[serde(rename_all = "camelCase")]
483#[non_exhaustive]
484pub struct NesContextCapabilities {
485 #[serde_as(deserialize_as = "DefaultOnError")]
487 #[schemars(extend("x-deserialize-default-on-error" = true))]
488 #[serde(default)]
489 pub recent_files: Option<NesRecentFilesCapabilities>,
490 #[serde_as(deserialize_as = "DefaultOnError")]
492 #[schemars(extend("x-deserialize-default-on-error" = true))]
493 #[serde(default)]
494 pub related_snippets: Option<NesRelatedSnippetsCapabilities>,
495 #[serde_as(deserialize_as = "DefaultOnError")]
497 #[schemars(extend("x-deserialize-default-on-error" = true))]
498 #[serde(default)]
499 pub edit_history: Option<NesEditHistoryCapabilities>,
500 #[serde_as(deserialize_as = "DefaultOnError")]
502 #[schemars(extend("x-deserialize-default-on-error" = true))]
503 #[serde(default)]
504 pub user_actions: Option<NesUserActionsCapabilities>,
505 #[serde_as(deserialize_as = "DefaultOnError")]
507 #[schemars(extend("x-deserialize-default-on-error" = true))]
508 #[serde(default)]
509 pub open_files: Option<NesOpenFilesCapabilities>,
510 #[serde_as(deserialize_as = "DefaultOnError")]
512 #[schemars(extend("x-deserialize-default-on-error" = true))]
513 #[serde(default)]
514 pub diagnostics: Option<NesDiagnosticsCapabilities>,
515 #[serde(rename = "_meta")]
521 pub meta: Option<Meta>,
522}
523
524impl NesContextCapabilities {
525 #[must_use]
526 pub fn new() -> Self {
527 Self::default()
528 }
529
530 #[must_use]
531 pub fn recent_files(
532 mut self,
533 recent_files: impl IntoOption<NesRecentFilesCapabilities>,
534 ) -> Self {
535 self.recent_files = recent_files.into_option();
536 self
537 }
538
539 #[must_use]
540 pub fn related_snippets(
541 mut self,
542 related_snippets: impl IntoOption<NesRelatedSnippetsCapabilities>,
543 ) -> Self {
544 self.related_snippets = related_snippets.into_option();
545 self
546 }
547
548 #[must_use]
549 pub fn edit_history(
550 mut self,
551 edit_history: impl IntoOption<NesEditHistoryCapabilities>,
552 ) -> Self {
553 self.edit_history = edit_history.into_option();
554 self
555 }
556
557 #[must_use]
558 pub fn user_actions(
559 mut self,
560 user_actions: impl IntoOption<NesUserActionsCapabilities>,
561 ) -> Self {
562 self.user_actions = user_actions.into_option();
563 self
564 }
565
566 #[must_use]
567 pub fn open_files(mut self, open_files: impl IntoOption<NesOpenFilesCapabilities>) -> Self {
568 self.open_files = open_files.into_option();
569 self
570 }
571
572 #[must_use]
573 pub fn diagnostics(mut self, diagnostics: impl IntoOption<NesDiagnosticsCapabilities>) -> Self {
574 self.diagnostics = diagnostics.into_option();
575 self
576 }
577
578 #[must_use]
584 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
585 self.meta = meta.into_option();
586 self
587 }
588}
589
590#[skip_serializing_none]
592#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
593#[serde(rename_all = "camelCase")]
594#[non_exhaustive]
595pub struct NesRecentFilesCapabilities {
596 pub max_count: Option<u32>,
598 #[serde(rename = "_meta")]
604 pub meta: Option<Meta>,
605}
606
607impl NesRecentFilesCapabilities {
608 #[must_use]
609 pub fn new() -> Self {
610 Self::default()
611 }
612}
613
614#[skip_serializing_none]
616#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
617#[serde(rename_all = "camelCase")]
618#[non_exhaustive]
619pub struct NesRelatedSnippetsCapabilities {
620 #[serde(rename = "_meta")]
626 pub meta: Option<Meta>,
627}
628
629impl NesRelatedSnippetsCapabilities {
630 #[must_use]
631 pub fn new() -> Self {
632 Self::default()
633 }
634}
635
636#[skip_serializing_none]
638#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
639#[serde(rename_all = "camelCase")]
640#[non_exhaustive]
641pub struct NesEditHistoryCapabilities {
642 pub max_count: Option<u32>,
644 #[serde(rename = "_meta")]
650 pub meta: Option<Meta>,
651}
652
653impl NesEditHistoryCapabilities {
654 #[must_use]
655 pub fn new() -> Self {
656 Self::default()
657 }
658}
659
660#[skip_serializing_none]
662#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
663#[serde(rename_all = "camelCase")]
664#[non_exhaustive]
665pub struct NesUserActionsCapabilities {
666 pub max_count: Option<u32>,
668 #[serde(rename = "_meta")]
674 pub meta: Option<Meta>,
675}
676
677impl NesUserActionsCapabilities {
678 #[must_use]
679 pub fn new() -> Self {
680 Self::default()
681 }
682}
683
684#[skip_serializing_none]
686#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
687#[serde(rename_all = "camelCase")]
688#[non_exhaustive]
689pub struct NesOpenFilesCapabilities {
690 #[serde(rename = "_meta")]
696 pub meta: Option<Meta>,
697}
698
699impl NesOpenFilesCapabilities {
700 #[must_use]
701 pub fn new() -> Self {
702 Self::default()
703 }
704}
705
706#[skip_serializing_none]
708#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
709#[serde(rename_all = "camelCase")]
710#[non_exhaustive]
711pub struct NesDiagnosticsCapabilities {
712 #[serde(rename = "_meta")]
718 pub meta: Option<Meta>,
719}
720
721impl NesDiagnosticsCapabilities {
722 #[must_use]
723 pub fn new() -> Self {
724 Self::default()
725 }
726}
727
728#[serde_as]
732#[skip_serializing_none]
733#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
734#[serde(rename_all = "camelCase")]
735#[non_exhaustive]
736pub struct ClientNesCapabilities {
737 #[serde_as(deserialize_as = "DefaultOnError")]
739 #[schemars(extend("x-deserialize-default-on-error" = true))]
740 #[serde(default)]
741 pub jump: Option<NesJumpCapabilities>,
742 #[serde_as(deserialize_as = "DefaultOnError")]
744 #[schemars(extend("x-deserialize-default-on-error" = true))]
745 #[serde(default)]
746 pub rename: Option<NesRenameCapabilities>,
747 #[serde_as(deserialize_as = "DefaultOnError")]
749 #[schemars(extend("x-deserialize-default-on-error" = true))]
750 #[serde(default)]
751 pub search_and_replace: Option<NesSearchAndReplaceCapabilities>,
752 #[serde(rename = "_meta")]
758 pub meta: Option<Meta>,
759}
760
761impl ClientNesCapabilities {
762 #[must_use]
763 pub fn new() -> Self {
764 Self::default()
765 }
766
767 #[must_use]
768 pub fn jump(mut self, jump: impl IntoOption<NesJumpCapabilities>) -> Self {
769 self.jump = jump.into_option();
770 self
771 }
772
773 #[must_use]
774 pub fn rename(mut self, rename: impl IntoOption<NesRenameCapabilities>) -> Self {
775 self.rename = rename.into_option();
776 self
777 }
778
779 #[must_use]
780 pub fn search_and_replace(
781 mut self,
782 search_and_replace: impl IntoOption<NesSearchAndReplaceCapabilities>,
783 ) -> Self {
784 self.search_and_replace = search_and_replace.into_option();
785 self
786 }
787
788 #[must_use]
794 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
795 self.meta = meta.into_option();
796 self
797 }
798}
799
800#[skip_serializing_none]
802#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
803#[serde(rename_all = "camelCase")]
804#[non_exhaustive]
805pub struct NesJumpCapabilities {
806 #[serde(rename = "_meta")]
812 pub meta: Option<Meta>,
813}
814
815impl NesJumpCapabilities {
816 #[must_use]
817 pub fn new() -> Self {
818 Self::default()
819 }
820}
821
822#[skip_serializing_none]
824#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
825#[serde(rename_all = "camelCase")]
826#[non_exhaustive]
827pub struct NesRenameCapabilities {
828 #[serde(rename = "_meta")]
834 pub meta: Option<Meta>,
835}
836
837impl NesRenameCapabilities {
838 #[must_use]
839 pub fn new() -> Self {
840 Self::default()
841 }
842}
843
844#[skip_serializing_none]
846#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
847#[serde(rename_all = "camelCase")]
848#[non_exhaustive]
849pub struct NesSearchAndReplaceCapabilities {
850 #[serde(rename = "_meta")]
856 pub meta: Option<Meta>,
857}
858
859impl NesSearchAndReplaceCapabilities {
860 #[must_use]
861 pub fn new() -> Self {
862 Self::default()
863 }
864}
865
866#[skip_serializing_none]
870#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
871#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_OPEN_METHOD_NAME))]
872#[serde(rename_all = "camelCase")]
873#[non_exhaustive]
874pub struct DidOpenDocumentNotification {
875 pub session_id: SessionId,
877 pub uri: String,
879 pub language_id: String,
881 pub version: i64,
883 pub text: String,
885 #[serde(rename = "_meta")]
891 pub meta: Option<Meta>,
892}
893
894impl DidOpenDocumentNotification {
895 #[must_use]
896 pub fn new(
897 session_id: impl Into<SessionId>,
898 uri: impl Into<String>,
899 language_id: impl Into<String>,
900 version: i64,
901 text: impl Into<String>,
902 ) -> Self {
903 Self {
904 session_id: session_id.into(),
905 uri: uri.into(),
906 language_id: language_id.into(),
907 version,
908 text: text.into(),
909 meta: None,
910 }
911 }
912
913 #[must_use]
919 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
920 self.meta = meta.into_option();
921 self
922 }
923}
924
925#[skip_serializing_none]
927#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
928#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_CHANGE_METHOD_NAME))]
929#[serde(rename_all = "camelCase")]
930#[non_exhaustive]
931pub struct DidChangeDocumentNotification {
932 pub session_id: SessionId,
934 pub uri: String,
936 pub version: i64,
938 pub content_changes: Vec<TextDocumentContentChangeEvent>,
940 #[serde(rename = "_meta")]
946 pub meta: Option<Meta>,
947}
948
949impl DidChangeDocumentNotification {
950 #[must_use]
951 pub fn new(
952 session_id: impl Into<SessionId>,
953 uri: impl Into<String>,
954 version: i64,
955 content_changes: Vec<TextDocumentContentChangeEvent>,
956 ) -> Self {
957 Self {
958 session_id: session_id.into(),
959 uri: uri.into(),
960 version,
961 content_changes,
962 meta: None,
963 }
964 }
965
966 #[must_use]
972 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
973 self.meta = meta.into_option();
974 self
975 }
976}
977
978#[skip_serializing_none]
983#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
984#[serde(rename_all = "camelCase")]
985#[non_exhaustive]
986pub struct TextDocumentContentChangeEvent {
987 pub range: Option<Range>,
989 pub text: String,
991 #[serde(rename = "_meta")]
997 pub meta: Option<Meta>,
998}
999
1000impl TextDocumentContentChangeEvent {
1001 #[must_use]
1002 pub fn full(text: impl Into<String>) -> Self {
1003 Self {
1004 range: None,
1005 text: text.into(),
1006 meta: None,
1007 }
1008 }
1009
1010 #[must_use]
1011 pub fn incremental(range: Range, text: impl Into<String>) -> Self {
1012 Self {
1013 range: Some(range),
1014 text: text.into(),
1015 meta: None,
1016 }
1017 }
1018
1019 #[must_use]
1025 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1026 self.meta = meta.into_option();
1027 self
1028 }
1029}
1030
1031#[skip_serializing_none]
1033#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1034#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_CLOSE_METHOD_NAME))]
1035#[serde(rename_all = "camelCase")]
1036#[non_exhaustive]
1037pub struct DidCloseDocumentNotification {
1038 pub session_id: SessionId,
1040 pub uri: String,
1042 #[serde(rename = "_meta")]
1048 pub meta: Option<Meta>,
1049}
1050
1051impl DidCloseDocumentNotification {
1052 #[must_use]
1053 pub fn new(session_id: impl Into<SessionId>, uri: impl Into<String>) -> Self {
1054 Self {
1055 session_id: session_id.into(),
1056 uri: uri.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_SAVE_METHOD_NAME))]
1077#[serde(rename_all = "camelCase")]
1078#[non_exhaustive]
1079pub struct DidSaveDocumentNotification {
1080 pub session_id: SessionId,
1082 pub uri: String,
1084 #[serde(rename = "_meta")]
1090 pub meta: Option<Meta>,
1091}
1092
1093impl DidSaveDocumentNotification {
1094 #[must_use]
1095 pub fn new(session_id: impl Into<SessionId>, uri: impl Into<String>) -> Self {
1096 Self {
1097 session_id: session_id.into(),
1098 uri: uri.into(),
1099 meta: None,
1100 }
1101 }
1102
1103 #[must_use]
1109 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1110 self.meta = meta.into_option();
1111 self
1112 }
1113}
1114
1115#[skip_serializing_none]
1117#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1118#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_FOCUS_METHOD_NAME))]
1119#[serde(rename_all = "camelCase")]
1120#[non_exhaustive]
1121pub struct DidFocusDocumentNotification {
1122 pub session_id: SessionId,
1124 pub uri: String,
1126 pub version: i64,
1128 pub position: Position,
1130 pub visible_range: Range,
1132 #[serde(rename = "_meta")]
1138 pub meta: Option<Meta>,
1139}
1140
1141impl DidFocusDocumentNotification {
1142 #[must_use]
1143 pub fn new(
1144 session_id: impl Into<SessionId>,
1145 uri: impl Into<String>,
1146 version: i64,
1147 position: Position,
1148 visible_range: Range,
1149 ) -> Self {
1150 Self {
1151 session_id: session_id.into(),
1152 uri: uri.into(),
1153 version,
1154 position,
1155 visible_range,
1156 meta: None,
1157 }
1158 }
1159
1160 #[must_use]
1166 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1167 self.meta = meta.into_option();
1168 self
1169 }
1170}
1171
1172#[serde_as]
1176#[skip_serializing_none]
1177#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1178#[schemars(extend("x-side" = "agent", "x-method" = NES_START_METHOD_NAME))]
1179#[serde(rename_all = "camelCase")]
1180#[non_exhaustive]
1181pub struct StartNesRequest {
1182 pub workspace_uri: Option<String>,
1184 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1186 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1187 #[serde(default)]
1188 pub workspace_folders: Option<Vec<WorkspaceFolder>>,
1189 #[serde_as(deserialize_as = "DefaultOnError")]
1191 #[schemars(extend("x-deserialize-default-on-error" = true))]
1192 #[serde(default)]
1193 pub repository: Option<NesRepository>,
1194 #[serde(rename = "_meta")]
1200 pub meta: Option<Meta>,
1201}
1202
1203impl StartNesRequest {
1204 #[must_use]
1205 pub fn new() -> Self {
1206 Self {
1207 workspace_uri: None,
1208 workspace_folders: None,
1209 repository: None,
1210 meta: None,
1211 }
1212 }
1213
1214 #[must_use]
1215 pub fn workspace_uri(mut self, workspace_uri: impl IntoOption<String>) -> Self {
1216 self.workspace_uri = workspace_uri.into_option();
1217 self
1218 }
1219
1220 #[must_use]
1221 pub fn workspace_folders(
1222 mut self,
1223 workspace_folders: impl IntoOption<Vec<WorkspaceFolder>>,
1224 ) -> Self {
1225 self.workspace_folders = workspace_folders.into_option();
1226 self
1227 }
1228
1229 #[must_use]
1230 pub fn repository(mut self, repository: impl IntoOption<NesRepository>) -> Self {
1231 self.repository = repository.into_option();
1232 self
1233 }
1234
1235 #[must_use]
1241 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1242 self.meta = meta.into_option();
1243 self
1244 }
1245}
1246
1247impl Default for StartNesRequest {
1248 fn default() -> Self {
1249 Self::new()
1250 }
1251}
1252
1253#[skip_serializing_none]
1255#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1256#[serde(rename_all = "camelCase")]
1257#[non_exhaustive]
1258pub struct WorkspaceFolder {
1259 pub uri: String,
1261 pub name: String,
1263 #[serde(rename = "_meta")]
1269 pub meta: Option<Meta>,
1270}
1271
1272impl WorkspaceFolder {
1273 #[must_use]
1274 pub fn new(uri: impl Into<String>, name: impl Into<String>) -> Self {
1275 Self {
1276 uri: uri.into(),
1277 name: name.into(),
1278 meta: None,
1279 }
1280 }
1281
1282 #[must_use]
1288 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1289 self.meta = meta.into_option();
1290 self
1291 }
1292}
1293
1294#[skip_serializing_none]
1296#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1297#[serde(rename_all = "camelCase")]
1298#[non_exhaustive]
1299pub struct NesRepository {
1300 pub name: String,
1302 pub owner: String,
1304 pub remote_url: String,
1306 #[serde(rename = "_meta")]
1312 pub meta: Option<Meta>,
1313}
1314
1315impl NesRepository {
1316 #[must_use]
1317 pub fn new(
1318 name: impl Into<String>,
1319 owner: impl Into<String>,
1320 remote_url: impl Into<String>,
1321 ) -> Self {
1322 Self {
1323 name: name.into(),
1324 owner: owner.into(),
1325 remote_url: remote_url.into(),
1326 meta: None,
1327 }
1328 }
1329
1330 #[must_use]
1336 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1337 self.meta = meta.into_option();
1338 self
1339 }
1340}
1341
1342#[skip_serializing_none]
1344#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1345#[schemars(extend("x-side" = "agent", "x-method" = NES_START_METHOD_NAME))]
1346#[serde(rename_all = "camelCase")]
1347#[non_exhaustive]
1348pub struct StartNesResponse {
1349 pub session_id: SessionId,
1351 #[serde(rename = "_meta")]
1357 pub meta: Option<Meta>,
1358}
1359
1360impl StartNesResponse {
1361 #[must_use]
1362 pub fn new(session_id: impl Into<SessionId>) -> Self {
1363 Self {
1364 session_id: session_id.into(),
1365 meta: None,
1366 }
1367 }
1368
1369 #[must_use]
1375 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1376 self.meta = meta.into_option();
1377 self
1378 }
1379}
1380
1381#[skip_serializing_none]
1388#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1389#[schemars(extend("x-side" = "agent", "x-method" = NES_CLOSE_METHOD_NAME))]
1390#[serde(rename_all = "camelCase")]
1391#[non_exhaustive]
1392pub struct CloseNesRequest {
1393 pub session_id: SessionId,
1395 #[serde(rename = "_meta")]
1401 pub meta: Option<Meta>,
1402}
1403
1404impl CloseNesRequest {
1405 #[must_use]
1406 pub fn new(session_id: impl Into<SessionId>) -> Self {
1407 Self {
1408 session_id: session_id.into(),
1409 meta: None,
1410 }
1411 }
1412
1413 #[must_use]
1419 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1420 self.meta = meta.into_option();
1421 self
1422 }
1423}
1424
1425#[skip_serializing_none]
1427#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1428#[schemars(extend("x-side" = "agent", "x-method" = NES_CLOSE_METHOD_NAME))]
1429#[serde(rename_all = "camelCase")]
1430#[non_exhaustive]
1431pub struct CloseNesResponse {
1432 #[serde(rename = "_meta")]
1438 pub meta: Option<Meta>,
1439}
1440
1441impl CloseNesResponse {
1442 #[must_use]
1443 pub fn new() -> Self {
1444 Self::default()
1445 }
1446
1447 #[must_use]
1453 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1454 self.meta = meta.into_option();
1455 self
1456 }
1457}
1458
1459#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1463#[non_exhaustive]
1464pub enum NesTriggerKind {
1465 #[serde(rename = "automatic")]
1467 Automatic,
1468 #[serde(rename = "diagnostic")]
1470 Diagnostic,
1471 #[serde(rename = "manual")]
1473 Manual,
1474}
1475
1476#[serde_as]
1478#[skip_serializing_none]
1479#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1480#[schemars(extend("x-side" = "agent", "x-method" = NES_SUGGEST_METHOD_NAME))]
1481#[serde(rename_all = "camelCase")]
1482#[non_exhaustive]
1483pub struct SuggestNesRequest {
1484 pub session_id: SessionId,
1486 pub uri: String,
1488 pub version: i64,
1490 pub position: Position,
1492 #[serde_as(deserialize_as = "DefaultOnError")]
1494 #[schemars(extend("x-deserialize-default-on-error" = true))]
1495 #[serde(default)]
1496 pub selection: Option<Range>,
1497 pub trigger_kind: NesTriggerKind,
1499 #[serde_as(deserialize_as = "DefaultOnError")]
1501 #[schemars(extend("x-deserialize-default-on-error" = true))]
1502 #[serde(default)]
1503 pub context: Option<NesSuggestContext>,
1504 #[serde(rename = "_meta")]
1510 pub meta: Option<Meta>,
1511}
1512
1513impl SuggestNesRequest {
1514 #[must_use]
1515 pub fn new(
1516 session_id: impl Into<SessionId>,
1517 uri: impl Into<String>,
1518 version: i64,
1519 position: Position,
1520 trigger_kind: NesTriggerKind,
1521 ) -> Self {
1522 Self {
1523 session_id: session_id.into(),
1524 uri: uri.into(),
1525 version,
1526 position,
1527 selection: None,
1528 trigger_kind,
1529 context: None,
1530 meta: None,
1531 }
1532 }
1533
1534 #[must_use]
1535 pub fn selection(mut self, selection: impl IntoOption<Range>) -> Self {
1536 self.selection = selection.into_option();
1537 self
1538 }
1539
1540 #[must_use]
1541 pub fn context(mut self, context: impl IntoOption<NesSuggestContext>) -> Self {
1542 self.context = context.into_option();
1543 self
1544 }
1545
1546 #[must_use]
1552 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1553 self.meta = meta.into_option();
1554 self
1555 }
1556}
1557
1558#[serde_as]
1560#[skip_serializing_none]
1561#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1562#[serde(rename_all = "camelCase")]
1563#[non_exhaustive]
1564pub struct NesSuggestContext {
1565 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1567 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1568 #[serde(default)]
1569 pub recent_files: Option<Vec<NesRecentFile>>,
1570 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1572 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1573 #[serde(default)]
1574 pub related_snippets: Option<Vec<NesRelatedSnippet>>,
1575 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1577 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1578 #[serde(default)]
1579 pub edit_history: Option<Vec<NesEditHistoryEntry>>,
1580 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1582 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1583 #[serde(default)]
1584 pub user_actions: Option<Vec<NesUserAction>>,
1585 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1587 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1588 #[serde(default)]
1589 pub open_files: Option<Vec<NesOpenFile>>,
1590 #[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_, SkipListener>>>")]
1592 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1593 #[serde(default)]
1594 pub diagnostics: Option<Vec<NesDiagnostic>>,
1595 #[serde(rename = "_meta")]
1601 pub meta: Option<Meta>,
1602}
1603
1604impl NesSuggestContext {
1605 #[must_use]
1606 pub fn new() -> Self {
1607 Self::default()
1608 }
1609
1610 #[must_use]
1611 pub fn recent_files(mut self, recent_files: impl IntoOption<Vec<NesRecentFile>>) -> Self {
1612 self.recent_files = recent_files.into_option();
1613 self
1614 }
1615
1616 #[must_use]
1617 pub fn related_snippets(
1618 mut self,
1619 related_snippets: impl IntoOption<Vec<NesRelatedSnippet>>,
1620 ) -> Self {
1621 self.related_snippets = related_snippets.into_option();
1622 self
1623 }
1624
1625 #[must_use]
1626 pub fn edit_history(mut self, edit_history: impl IntoOption<Vec<NesEditHistoryEntry>>) -> Self {
1627 self.edit_history = edit_history.into_option();
1628 self
1629 }
1630
1631 #[must_use]
1632 pub fn user_actions(mut self, user_actions: impl IntoOption<Vec<NesUserAction>>) -> Self {
1633 self.user_actions = user_actions.into_option();
1634 self
1635 }
1636
1637 #[must_use]
1638 pub fn open_files(mut self, open_files: impl IntoOption<Vec<NesOpenFile>>) -> Self {
1639 self.open_files = open_files.into_option();
1640 self
1641 }
1642
1643 #[must_use]
1644 pub fn diagnostics(mut self, diagnostics: impl IntoOption<Vec<NesDiagnostic>>) -> Self {
1645 self.diagnostics = diagnostics.into_option();
1646 self
1647 }
1648
1649 #[must_use]
1655 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1656 self.meta = meta.into_option();
1657 self
1658 }
1659}
1660
1661#[skip_serializing_none]
1663#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1664#[serde(rename_all = "camelCase")]
1665#[non_exhaustive]
1666pub struct NesRecentFile {
1667 pub uri: String,
1669 pub language_id: String,
1671 pub text: String,
1673 #[serde(rename = "_meta")]
1679 pub meta: Option<Meta>,
1680}
1681
1682impl NesRecentFile {
1683 #[must_use]
1684 pub fn new(
1685 uri: impl Into<String>,
1686 language_id: impl Into<String>,
1687 text: impl Into<String>,
1688 ) -> Self {
1689 Self {
1690 uri: uri.into(),
1691 language_id: language_id.into(),
1692 text: text.into(),
1693 meta: None,
1694 }
1695 }
1696
1697 #[must_use]
1703 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1704 self.meta = meta.into_option();
1705 self
1706 }
1707}
1708
1709#[skip_serializing_none]
1711#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1712#[serde(rename_all = "camelCase")]
1713#[non_exhaustive]
1714pub struct NesRelatedSnippet {
1715 pub uri: String,
1717 pub excerpts: Vec<NesExcerpt>,
1719 #[serde(rename = "_meta")]
1725 pub meta: Option<Meta>,
1726}
1727
1728impl NesRelatedSnippet {
1729 #[must_use]
1730 pub fn new(uri: impl Into<String>, excerpts: Vec<NesExcerpt>) -> Self {
1731 Self {
1732 uri: uri.into(),
1733 excerpts,
1734 meta: None,
1735 }
1736 }
1737
1738 #[must_use]
1744 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1745 self.meta = meta.into_option();
1746 self
1747 }
1748}
1749
1750#[skip_serializing_none]
1752#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1753#[serde(rename_all = "camelCase")]
1754#[non_exhaustive]
1755pub struct NesExcerpt {
1756 pub start_line: u32,
1758 pub end_line: u32,
1760 pub text: String,
1762 #[serde(rename = "_meta")]
1768 pub meta: Option<Meta>,
1769}
1770
1771impl NesExcerpt {
1772 #[must_use]
1773 pub fn new(start_line: u32, end_line: u32, text: impl Into<String>) -> Self {
1774 Self {
1775 start_line,
1776 end_line,
1777 text: text.into(),
1778 meta: None,
1779 }
1780 }
1781
1782 #[must_use]
1788 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1789 self.meta = meta.into_option();
1790 self
1791 }
1792}
1793
1794#[skip_serializing_none]
1796#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1797#[serde(rename_all = "camelCase")]
1798#[non_exhaustive]
1799pub struct NesEditHistoryEntry {
1800 pub uri: String,
1802 pub diff: String,
1804 #[serde(rename = "_meta")]
1810 pub meta: Option<Meta>,
1811}
1812
1813impl NesEditHistoryEntry {
1814 #[must_use]
1815 pub fn new(uri: impl Into<String>, diff: impl Into<String>) -> Self {
1816 Self {
1817 uri: uri.into(),
1818 diff: diff.into(),
1819 meta: None,
1820 }
1821 }
1822
1823 #[must_use]
1829 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1830 self.meta = meta.into_option();
1831 self
1832 }
1833}
1834
1835#[skip_serializing_none]
1837#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1838#[serde(rename_all = "camelCase")]
1839#[non_exhaustive]
1840pub struct NesUserAction {
1841 pub action: String,
1843 pub uri: String,
1845 pub position: Position,
1847 pub timestamp_ms: u64,
1849 #[serde(rename = "_meta")]
1855 pub meta: Option<Meta>,
1856}
1857
1858impl NesUserAction {
1859 #[must_use]
1860 pub fn new(
1861 action: impl Into<String>,
1862 uri: impl Into<String>,
1863 position: Position,
1864 timestamp_ms: u64,
1865 ) -> Self {
1866 Self {
1867 action: action.into(),
1868 uri: uri.into(),
1869 position,
1870 timestamp_ms,
1871 meta: None,
1872 }
1873 }
1874
1875 #[must_use]
1881 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1882 self.meta = meta.into_option();
1883 self
1884 }
1885}
1886
1887#[serde_as]
1889#[skip_serializing_none]
1890#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1891#[serde(rename_all = "camelCase")]
1892#[non_exhaustive]
1893pub struct NesOpenFile {
1894 pub uri: String,
1896 pub language_id: String,
1898 #[serde_as(deserialize_as = "DefaultOnError")]
1900 #[schemars(extend("x-deserialize-default-on-error" = true))]
1901 #[serde(default)]
1902 pub visible_range: Option<Range>,
1903 #[serde_as(deserialize_as = "DefaultOnError")]
1905 #[schemars(extend("x-deserialize-default-on-error" = true))]
1906 #[serde(default)]
1907 pub last_focused_ms: Option<u64>,
1908 #[serde(rename = "_meta")]
1914 pub meta: Option<Meta>,
1915}
1916
1917impl NesOpenFile {
1918 #[must_use]
1919 pub fn new(uri: impl Into<String>, language_id: impl Into<String>) -> Self {
1920 Self {
1921 uri: uri.into(),
1922 language_id: language_id.into(),
1923 visible_range: None,
1924 last_focused_ms: None,
1925 meta: None,
1926 }
1927 }
1928
1929 #[must_use]
1930 pub fn visible_range(mut self, visible_range: impl IntoOption<Range>) -> Self {
1931 self.visible_range = visible_range.into_option();
1932 self
1933 }
1934
1935 #[must_use]
1936 pub fn last_focused_ms(mut self, last_focused_ms: impl IntoOption<u64>) -> Self {
1937 self.last_focused_ms = last_focused_ms.into_option();
1938 self
1939 }
1940
1941 #[must_use]
1947 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1948 self.meta = meta.into_option();
1949 self
1950 }
1951}
1952
1953#[skip_serializing_none]
1955#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1956#[serde(rename_all = "camelCase")]
1957#[non_exhaustive]
1958pub struct NesDiagnostic {
1959 pub uri: String,
1961 pub range: Range,
1963 pub severity: NesDiagnosticSeverity,
1965 pub message: String,
1967 #[serde(rename = "_meta")]
1973 pub meta: Option<Meta>,
1974}
1975
1976impl NesDiagnostic {
1977 #[must_use]
1978 pub fn new(
1979 uri: impl Into<String>,
1980 range: Range,
1981 severity: NesDiagnosticSeverity,
1982 message: impl Into<String>,
1983 ) -> Self {
1984 Self {
1985 uri: uri.into(),
1986 range,
1987 severity,
1988 message: message.into(),
1989 meta: None,
1990 }
1991 }
1992
1993 #[must_use]
1999 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2000 self.meta = meta.into_option();
2001 self
2002 }
2003}
2004
2005#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2007#[non_exhaustive]
2008pub enum NesDiagnosticSeverity {
2009 #[serde(rename = "error")]
2011 Error,
2012 #[serde(rename = "warning")]
2014 Warning,
2015 #[serde(rename = "information")]
2017 Information,
2018 #[serde(rename = "hint")]
2020 Hint,
2021}
2022
2023#[serde_as]
2027#[skip_serializing_none]
2028#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2029#[schemars(extend("x-side" = "agent", "x-method" = NES_SUGGEST_METHOD_NAME))]
2030#[serde(rename_all = "camelCase")]
2031#[non_exhaustive]
2032pub struct SuggestNesResponse {
2033 #[serde_as(deserialize_as = "DefaultOnError<VecSkipError<_, SkipListener>>")]
2035 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
2036 pub suggestions: Vec<NesSuggestion>,
2037 #[serde(rename = "_meta")]
2043 pub meta: Option<Meta>,
2044}
2045
2046impl SuggestNesResponse {
2047 #[must_use]
2048 pub fn new(suggestions: Vec<NesSuggestion>) -> Self {
2049 Self {
2050 suggestions,
2051 meta: None,
2052 }
2053 }
2054
2055 #[must_use]
2061 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2062 self.meta = meta.into_option();
2063 self
2064 }
2065}
2066
2067#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2069#[serde(tag = "kind", rename_all = "camelCase")]
2070#[schemars(extend("discriminator" = {"propertyName": "kind"}))]
2071#[non_exhaustive]
2072pub enum NesSuggestion {
2073 Edit(NesEditSuggestion),
2075 Jump(NesJumpSuggestion),
2077 Rename(NesRenameSuggestion),
2079 SearchAndReplace(NesSearchAndReplaceSuggestion),
2081}
2082
2083#[serde_as]
2085#[skip_serializing_none]
2086#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2087#[serde(rename_all = "camelCase")]
2088#[non_exhaustive]
2089pub struct NesEditSuggestion {
2090 pub id: String,
2092 pub uri: String,
2094 pub edits: Vec<NesTextEdit>,
2096 #[serde_as(deserialize_as = "DefaultOnError")]
2098 #[schemars(extend("x-deserialize-default-on-error" = true))]
2099 #[serde(default)]
2100 pub cursor_position: Option<Position>,
2101 #[serde(rename = "_meta")]
2107 pub meta: Option<Meta>,
2108}
2109
2110impl NesEditSuggestion {
2111 #[must_use]
2112 pub fn new(id: impl Into<String>, uri: impl Into<String>, edits: Vec<NesTextEdit>) -> Self {
2113 Self {
2114 id: id.into(),
2115 uri: uri.into(),
2116 edits,
2117 cursor_position: None,
2118 meta: None,
2119 }
2120 }
2121
2122 #[must_use]
2123 pub fn cursor_position(mut self, cursor_position: impl IntoOption<Position>) -> Self {
2124 self.cursor_position = cursor_position.into_option();
2125 self
2126 }
2127
2128 #[must_use]
2134 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2135 self.meta = meta.into_option();
2136 self
2137 }
2138}
2139
2140#[skip_serializing_none]
2142#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2143#[serde(rename_all = "camelCase")]
2144#[non_exhaustive]
2145pub struct NesTextEdit {
2146 pub range: Range,
2148 pub new_text: String,
2150 #[serde(rename = "_meta")]
2156 pub meta: Option<Meta>,
2157}
2158
2159impl NesTextEdit {
2160 #[must_use]
2161 pub fn new(range: Range, new_text: impl Into<String>) -> Self {
2162 Self {
2163 range,
2164 new_text: new_text.into(),
2165 meta: None,
2166 }
2167 }
2168
2169 #[must_use]
2175 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2176 self.meta = meta.into_option();
2177 self
2178 }
2179}
2180
2181#[skip_serializing_none]
2183#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2184#[serde(rename_all = "camelCase")]
2185#[non_exhaustive]
2186pub struct NesJumpSuggestion {
2187 pub id: String,
2189 pub uri: String,
2191 pub position: Position,
2193 #[serde(rename = "_meta")]
2199 pub meta: Option<Meta>,
2200}
2201
2202impl NesJumpSuggestion {
2203 #[must_use]
2204 pub fn new(id: impl Into<String>, uri: impl Into<String>, position: Position) -> Self {
2205 Self {
2206 id: id.into(),
2207 uri: uri.into(),
2208 position,
2209 meta: None,
2210 }
2211 }
2212
2213 #[must_use]
2219 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2220 self.meta = meta.into_option();
2221 self
2222 }
2223}
2224
2225#[skip_serializing_none]
2227#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2228#[serde(rename_all = "camelCase")]
2229#[non_exhaustive]
2230pub struct NesRenameSuggestion {
2231 pub id: String,
2233 pub uri: String,
2235 pub position: Position,
2237 pub new_name: String,
2239 #[serde(rename = "_meta")]
2245 pub meta: Option<Meta>,
2246}
2247
2248impl NesRenameSuggestion {
2249 #[must_use]
2250 pub fn new(
2251 id: impl Into<String>,
2252 uri: impl Into<String>,
2253 position: Position,
2254 new_name: impl Into<String>,
2255 ) -> Self {
2256 Self {
2257 id: id.into(),
2258 uri: uri.into(),
2259 position,
2260 new_name: new_name.into(),
2261 meta: None,
2262 }
2263 }
2264
2265 #[must_use]
2271 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2272 self.meta = meta.into_option();
2273 self
2274 }
2275}
2276
2277#[skip_serializing_none]
2279#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2280#[serde(rename_all = "camelCase")]
2281#[non_exhaustive]
2282pub struct NesSearchAndReplaceSuggestion {
2283 pub id: String,
2285 pub uri: String,
2287 pub search: String,
2289 pub replace: String,
2291 pub is_regex: Option<bool>,
2293 #[serde(rename = "_meta")]
2299 pub meta: Option<Meta>,
2300}
2301
2302impl NesSearchAndReplaceSuggestion {
2303 #[must_use]
2304 pub fn new(
2305 id: impl Into<String>,
2306 uri: impl Into<String>,
2307 search: impl Into<String>,
2308 replace: impl Into<String>,
2309 ) -> Self {
2310 Self {
2311 id: id.into(),
2312 uri: uri.into(),
2313 search: search.into(),
2314 replace: replace.into(),
2315 is_regex: None,
2316 meta: None,
2317 }
2318 }
2319
2320 #[must_use]
2321 pub fn is_regex(mut self, is_regex: impl IntoOption<bool>) -> Self {
2322 self.is_regex = is_regex.into_option();
2323 self
2324 }
2325
2326 #[must_use]
2332 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2333 self.meta = meta.into_option();
2334 self
2335 }
2336}
2337
2338#[skip_serializing_none]
2342#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2343#[schemars(extend("x-side" = "agent", "x-method" = NES_ACCEPT_METHOD_NAME))]
2344#[serde(rename_all = "camelCase")]
2345#[non_exhaustive]
2346pub struct AcceptNesNotification {
2347 pub session_id: SessionId,
2349 pub id: String,
2351 #[serde(rename = "_meta")]
2357 pub meta: Option<Meta>,
2358}
2359
2360impl AcceptNesNotification {
2361 #[must_use]
2362 pub fn new(session_id: impl Into<SessionId>, id: impl Into<String>) -> Self {
2363 Self {
2364 session_id: session_id.into(),
2365 id: id.into(),
2366 meta: None,
2367 }
2368 }
2369
2370 #[must_use]
2376 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2377 self.meta = meta.into_option();
2378 self
2379 }
2380}
2381
2382#[serde_as]
2384#[skip_serializing_none]
2385#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2386#[schemars(extend("x-side" = "agent", "x-method" = NES_REJECT_METHOD_NAME))]
2387#[serde(rename_all = "camelCase")]
2388#[non_exhaustive]
2389pub struct RejectNesNotification {
2390 pub session_id: SessionId,
2392 pub id: String,
2394 #[serde_as(deserialize_as = "DefaultOnError")]
2396 #[schemars(extend("x-deserialize-default-on-error" = true))]
2397 #[serde(default)]
2398 pub reason: Option<NesRejectReason>,
2399 #[serde(rename = "_meta")]
2405 pub meta: Option<Meta>,
2406}
2407
2408impl RejectNesNotification {
2409 #[must_use]
2410 pub fn new(session_id: impl Into<SessionId>, id: impl Into<String>) -> Self {
2411 Self {
2412 session_id: session_id.into(),
2413 id: id.into(),
2414 reason: None,
2415 meta: None,
2416 }
2417 }
2418
2419 #[must_use]
2420 pub fn reason(mut self, reason: impl IntoOption<NesRejectReason>) -> Self {
2421 self.reason = reason.into_option();
2422 self
2423 }
2424
2425 #[must_use]
2431 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2432 self.meta = meta.into_option();
2433 self
2434 }
2435}
2436
2437#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2439#[non_exhaustive]
2440pub enum NesRejectReason {
2441 #[serde(rename = "rejected")]
2443 Rejected,
2444 #[serde(rename = "ignored")]
2446 Ignored,
2447 #[serde(rename = "replaced")]
2449 Replaced,
2450 #[serde(rename = "cancelled")]
2452 Cancelled,
2453}
2454
2455#[cfg(test)]
2456mod tests {
2457 use super::*;
2458 use serde_json::json;
2459
2460 #[test]
2461 fn test_position_encoding_kind_serialization() {
2462 assert_eq!(
2463 serde_json::to_value(&PositionEncodingKind::Utf16).unwrap(),
2464 json!("utf-16")
2465 );
2466 assert_eq!(
2467 serde_json::to_value(&PositionEncodingKind::Utf32).unwrap(),
2468 json!("utf-32")
2469 );
2470 assert_eq!(
2471 serde_json::to_value(&PositionEncodingKind::Utf8).unwrap(),
2472 json!("utf-8")
2473 );
2474
2475 assert_eq!(
2476 serde_json::from_value::<PositionEncodingKind>(json!("utf-16")).unwrap(),
2477 PositionEncodingKind::Utf16
2478 );
2479 assert_eq!(
2480 serde_json::from_value::<PositionEncodingKind>(json!("utf-32")).unwrap(),
2481 PositionEncodingKind::Utf32
2482 );
2483 assert_eq!(
2484 serde_json::from_value::<PositionEncodingKind>(json!("utf-8")).unwrap(),
2485 PositionEncodingKind::Utf8
2486 );
2487 }
2488
2489 #[test]
2490 fn test_agent_nes_capabilities_serialization() {
2491 let caps = NesCapabilities::new()
2492 .events(
2493 NesEventCapabilities::new().document(
2494 NesDocumentEventCapabilities::new()
2495 .did_open(NesDocumentDidOpenCapabilities::default())
2496 .did_change(NesDocumentDidChangeCapabilities::new(
2497 TextDocumentSyncKind::Incremental,
2498 ))
2499 .did_close(NesDocumentDidCloseCapabilities::default())
2500 .did_save(NesDocumentDidSaveCapabilities::default())
2501 .did_focus(NesDocumentDidFocusCapabilities::default()),
2502 ),
2503 )
2504 .context(
2505 NesContextCapabilities::new()
2506 .recent_files(NesRecentFilesCapabilities {
2507 max_count: Some(10),
2508 meta: None,
2509 })
2510 .related_snippets(NesRelatedSnippetsCapabilities::default())
2511 .edit_history(NesEditHistoryCapabilities {
2512 max_count: Some(6),
2513 meta: None,
2514 })
2515 .user_actions(NesUserActionsCapabilities {
2516 max_count: Some(16),
2517 meta: None,
2518 })
2519 .open_files(NesOpenFilesCapabilities::default())
2520 .diagnostics(NesDiagnosticsCapabilities::default()),
2521 );
2522
2523 let json = serde_json::to_value(&caps).unwrap();
2524 assert_eq!(
2525 json,
2526 json!({
2527 "events": {
2528 "document": {
2529 "didOpen": {},
2530 "didChange": {
2531 "syncKind": "incremental"
2532 },
2533 "didClose": {},
2534 "didSave": {},
2535 "didFocus": {}
2536 }
2537 },
2538 "context": {
2539 "recentFiles": {
2540 "maxCount": 10
2541 },
2542 "relatedSnippets": {},
2543 "editHistory": {
2544 "maxCount": 6
2545 },
2546 "userActions": {
2547 "maxCount": 16
2548 },
2549 "openFiles": {},
2550 "diagnostics": {}
2551 }
2552 })
2553 );
2554
2555 let deserialized: NesCapabilities = serde_json::from_value(json).unwrap();
2557 assert_eq!(deserialized, caps);
2558 }
2559
2560 #[test]
2561 fn test_client_nes_capabilities_serialization() {
2562 let caps = ClientNesCapabilities::new()
2563 .jump(NesJumpCapabilities::default())
2564 .rename(NesRenameCapabilities::default())
2565 .search_and_replace(NesSearchAndReplaceCapabilities::default());
2566
2567 let json = serde_json::to_value(&caps).unwrap();
2568 assert_eq!(
2569 json,
2570 json!({
2571 "jump": {},
2572 "rename": {},
2573 "searchAndReplace": {}
2574 })
2575 );
2576
2577 let deserialized: ClientNesCapabilities = serde_json::from_value(json).unwrap();
2578 assert_eq!(deserialized, caps);
2579 }
2580
2581 #[test]
2582 fn test_document_did_open_serialization() {
2583 let notification = DidOpenDocumentNotification::new(
2584 "session_123",
2585 "file:///path/to/file.rs",
2586 "rust",
2587 1,
2588 "fn main() {\n println!(\"hello\");\n}\n",
2589 );
2590
2591 let json = serde_json::to_value(¬ification).unwrap();
2592 assert_eq!(
2593 json,
2594 json!({
2595 "sessionId": "session_123",
2596 "uri": "file:///path/to/file.rs",
2597 "languageId": "rust",
2598 "version": 1,
2599 "text": "fn main() {\n println!(\"hello\");\n}\n"
2600 })
2601 );
2602
2603 let deserialized: DidOpenDocumentNotification = serde_json::from_value(json).unwrap();
2604 assert_eq!(deserialized, notification);
2605 }
2606
2607 #[test]
2608 fn test_document_did_change_incremental_serialization() {
2609 let notification = DidChangeDocumentNotification::new(
2610 "session_123",
2611 "file:///path/to/file.rs",
2612 2,
2613 vec![TextDocumentContentChangeEvent::incremental(
2614 Range::new(Position::new(1, 4), Position::new(1, 4)),
2615 "let x = 42;\n ",
2616 )],
2617 );
2618
2619 let json = serde_json::to_value(¬ification).unwrap();
2620 assert_eq!(
2621 json,
2622 json!({
2623 "sessionId": "session_123",
2624 "uri": "file:///path/to/file.rs",
2625 "version": 2,
2626 "contentChanges": [
2627 {
2628 "range": {
2629 "start": { "line": 1, "character": 4 },
2630 "end": { "line": 1, "character": 4 }
2631 },
2632 "text": "let x = 42;\n "
2633 }
2634 ]
2635 })
2636 );
2637 }
2638
2639 #[test]
2640 fn test_document_did_change_full_serialization() {
2641 let notification = DidChangeDocumentNotification::new(
2642 "session_123",
2643 "file:///path/to/file.rs",
2644 2,
2645 vec![TextDocumentContentChangeEvent::full(
2646 "fn main() {\n let x = 42;\n println!(\"hello\");\n}\n",
2647 )],
2648 );
2649
2650 let json = serde_json::to_value(¬ification).unwrap();
2651 assert_eq!(
2652 json,
2653 json!({
2654 "sessionId": "session_123",
2655 "uri": "file:///path/to/file.rs",
2656 "version": 2,
2657 "contentChanges": [
2658 {
2659 "text": "fn main() {\n let x = 42;\n println!(\"hello\");\n}\n"
2660 }
2661 ]
2662 })
2663 );
2664 }
2665
2666 #[test]
2667 fn test_document_did_close_serialization() {
2668 let notification =
2669 DidCloseDocumentNotification::new("session_123", "file:///path/to/file.rs");
2670 let json = serde_json::to_value(¬ification).unwrap();
2671 assert_eq!(
2672 json,
2673 json!({ "sessionId": "session_123", "uri": "file:///path/to/file.rs" })
2674 );
2675 }
2676
2677 #[test]
2678 fn test_document_did_save_serialization() {
2679 let notification =
2680 DidSaveDocumentNotification::new("session_123", "file:///path/to/file.rs");
2681 let json = serde_json::to_value(¬ification).unwrap();
2682 assert_eq!(
2683 json,
2684 json!({ "sessionId": "session_123", "uri": "file:///path/to/file.rs" })
2685 );
2686 }
2687
2688 #[test]
2689 fn test_document_did_focus_serialization() {
2690 let notification = DidFocusDocumentNotification::new(
2691 "session_123",
2692 "file:///path/to/file.rs",
2693 2,
2694 Position::new(5, 12),
2695 Range::new(Position::new(0, 0), Position::new(45, 0)),
2696 );
2697
2698 let json = serde_json::to_value(¬ification).unwrap();
2699 assert_eq!(
2700 json,
2701 json!({
2702 "sessionId": "session_123",
2703 "uri": "file:///path/to/file.rs",
2704 "version": 2,
2705 "position": { "line": 5, "character": 12 },
2706 "visibleRange": {
2707 "start": { "line": 0, "character": 0 },
2708 "end": { "line": 45, "character": 0 }
2709 }
2710 })
2711 );
2712 }
2713
2714 #[test]
2715 fn test_nes_suggestion_edit_serialization() {
2716 let suggestion = NesSuggestion::Edit(
2717 NesEditSuggestion::new(
2718 "sugg_001",
2719 "file:///path/to/other_file.rs",
2720 vec![NesTextEdit::new(
2721 Range::new(Position::new(5, 0), Position::new(5, 10)),
2722 "let result = helper();",
2723 )],
2724 )
2725 .cursor_position(Position::new(5, 22)),
2726 );
2727
2728 let json = serde_json::to_value(&suggestion).unwrap();
2729 assert_eq!(
2730 json,
2731 json!({
2732 "kind": "edit",
2733 "id": "sugg_001",
2734 "uri": "file:///path/to/other_file.rs",
2735 "edits": [
2736 {
2737 "range": {
2738 "start": { "line": 5, "character": 0 },
2739 "end": { "line": 5, "character": 10 }
2740 },
2741 "newText": "let result = helper();"
2742 }
2743 ],
2744 "cursorPosition": { "line": 5, "character": 22 }
2745 })
2746 );
2747
2748 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
2749 assert_eq!(deserialized, suggestion);
2750 }
2751
2752 #[test]
2753 fn test_nes_suggestion_jump_serialization() {
2754 let suggestion = NesSuggestion::Jump(NesJumpSuggestion::new(
2755 "sugg_002",
2756 "file:///path/to/other_file.rs",
2757 Position::new(15, 4),
2758 ));
2759
2760 let json = serde_json::to_value(&suggestion).unwrap();
2761 assert_eq!(
2762 json,
2763 json!({
2764 "kind": "jump",
2765 "id": "sugg_002",
2766 "uri": "file:///path/to/other_file.rs",
2767 "position": { "line": 15, "character": 4 }
2768 })
2769 );
2770
2771 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
2772 assert_eq!(deserialized, suggestion);
2773 }
2774
2775 #[test]
2776 fn test_nes_suggestion_rename_serialization() {
2777 let suggestion = NesSuggestion::Rename(NesRenameSuggestion::new(
2778 "sugg_003",
2779 "file:///path/to/file.rs",
2780 Position::new(5, 10),
2781 "calculateTotal",
2782 ));
2783
2784 let json = serde_json::to_value(&suggestion).unwrap();
2785 assert_eq!(
2786 json,
2787 json!({
2788 "kind": "rename",
2789 "id": "sugg_003",
2790 "uri": "file:///path/to/file.rs",
2791 "position": { "line": 5, "character": 10 },
2792 "newName": "calculateTotal"
2793 })
2794 );
2795
2796 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
2797 assert_eq!(deserialized, suggestion);
2798 }
2799
2800 #[test]
2801 fn test_nes_suggestion_search_and_replace_serialization() {
2802 let suggestion = NesSuggestion::SearchAndReplace(
2803 NesSearchAndReplaceSuggestion::new(
2804 "sugg_004",
2805 "file:///path/to/file.rs",
2806 "oldFunction",
2807 "newFunction",
2808 )
2809 .is_regex(false),
2810 );
2811
2812 let json = serde_json::to_value(&suggestion).unwrap();
2813 assert_eq!(
2814 json,
2815 json!({
2816 "kind": "searchAndReplace",
2817 "id": "sugg_004",
2818 "uri": "file:///path/to/file.rs",
2819 "search": "oldFunction",
2820 "replace": "newFunction",
2821 "isRegex": false
2822 })
2823 );
2824
2825 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
2826 assert_eq!(deserialized, suggestion);
2827 }
2828
2829 #[test]
2830 fn test_nes_start_request_serialization() {
2831 let request = StartNesRequest::new()
2832 .workspace_uri("file:///Users/alice/projects/my-app")
2833 .workspace_folders(vec![WorkspaceFolder::new(
2834 "file:///Users/alice/projects/my-app",
2835 "my-app",
2836 )])
2837 .repository(NesRepository::new(
2838 "my-app",
2839 "alice",
2840 "https://github.com/alice/my-app.git",
2841 ));
2842
2843 let json = serde_json::to_value(&request).unwrap();
2844 assert_eq!(
2845 json,
2846 json!({
2847 "workspaceUri": "file:///Users/alice/projects/my-app",
2848 "workspaceFolders": [
2849 {
2850 "uri": "file:///Users/alice/projects/my-app",
2851 "name": "my-app"
2852 }
2853 ],
2854 "repository": {
2855 "name": "my-app",
2856 "owner": "alice",
2857 "remoteUrl": "https://github.com/alice/my-app.git"
2858 }
2859 })
2860 );
2861 }
2862
2863 #[test]
2864 fn test_nes_start_response_serialization() {
2865 let response = StartNesResponse::new("session_abc123");
2866 let json = serde_json::to_value(&response).unwrap();
2867 assert_eq!(json, json!({ "sessionId": "session_abc123" }));
2868 }
2869
2870 #[test]
2871 fn test_nes_trigger_kind_serialization() {
2872 assert_eq!(
2873 serde_json::to_value(&NesTriggerKind::Automatic).unwrap(),
2874 json!("automatic")
2875 );
2876 assert_eq!(
2877 serde_json::to_value(&NesTriggerKind::Diagnostic).unwrap(),
2878 json!("diagnostic")
2879 );
2880 assert_eq!(
2881 serde_json::to_value(&NesTriggerKind::Manual).unwrap(),
2882 json!("manual")
2883 );
2884 }
2885
2886 #[test]
2887 fn test_nes_reject_reason_serialization() {
2888 assert_eq!(
2889 serde_json::to_value(&NesRejectReason::Rejected).unwrap(),
2890 json!("rejected")
2891 );
2892 assert_eq!(
2893 serde_json::to_value(&NesRejectReason::Ignored).unwrap(),
2894 json!("ignored")
2895 );
2896 assert_eq!(
2897 serde_json::to_value(&NesRejectReason::Replaced).unwrap(),
2898 json!("replaced")
2899 );
2900 assert_eq!(
2901 serde_json::to_value(&NesRejectReason::Cancelled).unwrap(),
2902 json!("cancelled")
2903 );
2904 }
2905
2906 #[test]
2907 fn test_nes_accept_notification_serialization() {
2908 let notification = AcceptNesNotification::new("session_123", "sugg_001");
2909 let json = serde_json::to_value(¬ification).unwrap();
2910 assert_eq!(
2911 json,
2912 json!({ "sessionId": "session_123", "id": "sugg_001" })
2913 );
2914 }
2915
2916 #[test]
2917 fn test_nes_reject_notification_serialization() {
2918 let notification =
2919 RejectNesNotification::new("session_123", "sugg_001").reason(NesRejectReason::Rejected);
2920 let json = serde_json::to_value(¬ification).unwrap();
2921 assert_eq!(
2922 json,
2923 json!({ "sessionId": "session_123", "id": "sugg_001", "reason": "rejected" })
2924 );
2925 }
2926
2927 #[test]
2928 fn test_nes_suggest_request_with_context_serialization() {
2929 let request = SuggestNesRequest::new(
2930 "session_123",
2931 "file:///path/to/file.rs",
2932 2,
2933 Position::new(5, 12),
2934 NesTriggerKind::Automatic,
2935 )
2936 .selection(Range::new(Position::new(5, 4), Position::new(5, 12)))
2937 .context(
2938 NesSuggestContext::new()
2939 .recent_files(vec![NesRecentFile::new(
2940 "file:///path/to/utils.rs",
2941 "rust",
2942 "pub fn helper() -> i32 { 42 }\n",
2943 )])
2944 .diagnostics(vec![NesDiagnostic::new(
2945 "file:///path/to/file.rs",
2946 Range::new(Position::new(5, 0), Position::new(5, 10)),
2947 NesDiagnosticSeverity::Error,
2948 "cannot find value `foo` in this scope",
2949 )]),
2950 );
2951
2952 let json = serde_json::to_value(&request).unwrap();
2953 assert_eq!(json["sessionId"], "session_123");
2954 assert_eq!(json["uri"], "file:///path/to/file.rs");
2955 assert_eq!(json["version"], 2);
2956 assert_eq!(json["triggerKind"], "automatic");
2957 assert_eq!(
2958 json["context"]["recentFiles"][0]["uri"],
2959 "file:///path/to/utils.rs"
2960 );
2961 assert_eq!(json["context"]["diagnostics"][0]["severity"], "error");
2962 }
2963
2964 #[test]
2965 fn test_text_document_sync_kind_serialization() {
2966 assert_eq!(
2967 serde_json::to_value(&TextDocumentSyncKind::Full).unwrap(),
2968 json!("full")
2969 );
2970 assert_eq!(
2971 serde_json::to_value(&TextDocumentSyncKind::Incremental).unwrap(),
2972 json!("incremental")
2973 );
2974 }
2975
2976 #[test]
2977 fn test_document_did_change_capabilities_requires_sync_kind() {
2978 assert!(serde_json::from_value::<NesDocumentDidChangeCapabilities>(json!({})).is_err());
2979 }
2980
2981 #[test]
2982 fn test_nes_suggest_response_serialization() {
2983 let response = SuggestNesResponse::new(vec![
2984 NesSuggestion::Edit(NesEditSuggestion::new(
2985 "sugg_001",
2986 "file:///path/to/file.rs",
2987 vec![NesTextEdit::new(
2988 Range::new(Position::new(5, 0), Position::new(5, 10)),
2989 "let result = helper();",
2990 )],
2991 )),
2992 NesSuggestion::Jump(NesJumpSuggestion::new(
2993 "sugg_002",
2994 "file:///path/to/other.rs",
2995 Position::new(10, 0),
2996 )),
2997 ]);
2998
2999 let json = serde_json::to_value(&response).unwrap();
3000 assert_eq!(json["suggestions"].as_array().unwrap().len(), 2);
3001 assert_eq!(json["suggestions"][0]["kind"], "edit");
3002 assert_eq!(json["suggestions"][1]["kind"], "jump");
3003 }
3004}