1use std::{collections::BTreeMap, sync::Arc};
8
9use derive_more::{Display, From};
10use schemars::{JsonSchema, Schema};
11use serde::{Deserialize, Serialize};
12use serde_with::{DefaultOnError, VecSkipError, serde_as, skip_serializing_none};
13
14use super::{Meta, SessionId};
15use crate::{IntoOption, SkipListener};
16
17pub(crate) const NES_START_METHOD_NAME: &str = "nes/start";
21pub(crate) const NES_SUGGEST_METHOD_NAME: &str = "nes/suggest";
23pub(crate) const NES_ACCEPT_METHOD_NAME: &str = "nes/accept";
25pub(crate) const NES_REJECT_METHOD_NAME: &str = "nes/reject";
27
28#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, Display, From)]
34#[serde(transparent)]
35#[from(forward)]
36#[non_exhaustive]
37pub struct NesSuggestionId(pub Arc<str>);
38
39impl NesSuggestionId {
40 #[must_use]
42 pub fn new(id: impl Into<Self>) -> Self {
43 id.into()
44 }
45}
46pub(crate) const NES_CLOSE_METHOD_NAME: &str = "nes/close";
48pub(crate) const DOCUMENT_DID_OPEN_METHOD_NAME: &str = "document/didOpen";
50pub(crate) const DOCUMENT_DID_CHANGE_METHOD_NAME: &str = "document/didChange";
52pub(crate) const DOCUMENT_DID_CLOSE_METHOD_NAME: &str = "document/didClose";
54pub(crate) const DOCUMENT_DID_SAVE_METHOD_NAME: &str = "document/didSave";
56pub(crate) const DOCUMENT_DID_FOCUS_METHOD_NAME: &str = "document/didFocus";
58
59#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
65#[non_exhaustive]
66pub enum PositionEncodingKind {
67 #[serde(rename = "utf-16")]
69 Utf16,
70 #[serde(rename = "utf-32")]
72 Utf32,
73 #[serde(rename = "utf-8")]
75 Utf8,
76}
77
78#[serde_as]
82#[skip_serializing_none]
83#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
84#[serde(rename_all = "camelCase")]
85#[non_exhaustive]
86pub struct Position {
87 pub line: u32,
89 pub character: u32,
91 #[serde_as(deserialize_as = "DefaultOnError")]
97 #[schemars(extend("x-deserialize-default-on-error" = true))]
98 #[serde(default)]
99 #[serde(rename = "_meta")]
100 pub meta: Option<Meta>,
101}
102
103impl Position {
104 #[must_use]
106 pub fn new(line: u32, character: u32) -> Self {
107 Self {
108 line,
109 character,
110 meta: None,
111 }
112 }
113
114 #[must_use]
120 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
121 self.meta = meta.into_option();
122 self
123 }
124}
125
126#[serde_as]
128#[skip_serializing_none]
129#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
130#[serde(rename_all = "camelCase")]
131#[non_exhaustive]
132pub struct Range {
133 pub start: Position,
135 pub end: Position,
137 #[serde_as(deserialize_as = "DefaultOnError")]
143 #[schemars(extend("x-deserialize-default-on-error" = true))]
144 #[serde(default)]
145 #[serde(rename = "_meta")]
146 pub meta: Option<Meta>,
147}
148
149impl Range {
150 #[must_use]
152 pub fn new(start: Position, end: Position) -> Self {
153 Self {
154 start,
155 end,
156 meta: None,
157 }
158 }
159
160 #[must_use]
166 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
167 self.meta = meta.into_option();
168 self
169 }
170}
171
172#[serde_as]
179#[skip_serializing_none]
180#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
181#[serde(rename_all = "camelCase")]
182#[non_exhaustive]
183pub struct NesCapabilities {
184 #[serde_as(deserialize_as = "DefaultOnError")]
186 #[schemars(extend("x-deserialize-default-on-error" = true))]
187 #[serde(default)]
188 pub events: Option<NesEventCapabilities>,
189 #[serde_as(deserialize_as = "DefaultOnError")]
191 #[schemars(extend("x-deserialize-default-on-error" = true))]
192 #[serde(default)]
193 pub context: Option<NesContextCapabilities>,
194 #[serde_as(deserialize_as = "DefaultOnError")]
200 #[schemars(extend("x-deserialize-default-on-error" = true))]
201 #[serde(default)]
202 #[serde(rename = "_meta")]
203 pub meta: Option<Meta>,
204}
205
206impl NesCapabilities {
207 #[must_use]
209 pub fn new() -> Self {
210 Self::default()
211 }
212
213 #[must_use]
215 pub fn events(mut self, events: impl IntoOption<NesEventCapabilities>) -> Self {
216 self.events = events.into_option();
217 self
218 }
219
220 #[must_use]
222 pub fn context(mut self, context: impl IntoOption<NesContextCapabilities>) -> Self {
223 self.context = context.into_option();
224 self
225 }
226
227 #[must_use]
233 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
234 self.meta = meta.into_option();
235 self
236 }
237}
238
239#[serde_as]
241#[skip_serializing_none]
242#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
243#[serde(rename_all = "camelCase")]
244#[non_exhaustive]
245pub struct NesEventCapabilities {
246 #[serde_as(deserialize_as = "DefaultOnError")]
248 #[schemars(extend("x-deserialize-default-on-error" = true))]
249 #[serde(default)]
250 pub document: Option<NesDocumentEventCapabilities>,
251 #[serde_as(deserialize_as = "DefaultOnError")]
257 #[schemars(extend("x-deserialize-default-on-error" = true))]
258 #[serde(default)]
259 #[serde(rename = "_meta")]
260 pub meta: Option<Meta>,
261}
262
263impl NesEventCapabilities {
264 #[must_use]
266 pub fn new() -> Self {
267 Self::default()
268 }
269
270 #[must_use]
272 pub fn document(mut self, document: impl IntoOption<NesDocumentEventCapabilities>) -> Self {
273 self.document = document.into_option();
274 self
275 }
276
277 #[must_use]
283 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
284 self.meta = meta.into_option();
285 self
286 }
287}
288
289#[serde_as]
291#[skip_serializing_none]
292#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
293#[serde(rename_all = "camelCase")]
294#[non_exhaustive]
295pub struct NesDocumentEventCapabilities {
296 #[serde_as(deserialize_as = "DefaultOnError")]
298 #[schemars(extend("x-deserialize-default-on-error" = true))]
299 #[serde(default)]
300 pub did_open: Option<NesDocumentDidOpenCapabilities>,
301 #[serde_as(deserialize_as = "DefaultOnError")]
303 #[schemars(extend("x-deserialize-default-on-error" = true))]
304 #[serde(default)]
305 pub did_change: Option<NesDocumentDidChangeCapabilities>,
306 #[serde_as(deserialize_as = "DefaultOnError")]
308 #[schemars(extend("x-deserialize-default-on-error" = true))]
309 #[serde(default)]
310 pub did_close: Option<NesDocumentDidCloseCapabilities>,
311 #[serde_as(deserialize_as = "DefaultOnError")]
313 #[schemars(extend("x-deserialize-default-on-error" = true))]
314 #[serde(default)]
315 pub did_save: Option<NesDocumentDidSaveCapabilities>,
316 #[serde_as(deserialize_as = "DefaultOnError")]
318 #[schemars(extend("x-deserialize-default-on-error" = true))]
319 #[serde(default)]
320 pub did_focus: Option<NesDocumentDidFocusCapabilities>,
321 #[serde_as(deserialize_as = "DefaultOnError")]
327 #[schemars(extend("x-deserialize-default-on-error" = true))]
328 #[serde(default)]
329 #[serde(rename = "_meta")]
330 pub meta: Option<Meta>,
331}
332
333impl NesDocumentEventCapabilities {
334 #[must_use]
336 pub fn new() -> Self {
337 Self::default()
338 }
339
340 #[must_use]
342 pub fn did_open(mut self, did_open: impl IntoOption<NesDocumentDidOpenCapabilities>) -> Self {
343 self.did_open = did_open.into_option();
344 self
345 }
346
347 #[must_use]
349 pub fn did_change(
350 mut self,
351 did_change: impl IntoOption<NesDocumentDidChangeCapabilities>,
352 ) -> Self {
353 self.did_change = did_change.into_option();
354 self
355 }
356
357 #[must_use]
359 pub fn did_close(
360 mut self,
361 did_close: impl IntoOption<NesDocumentDidCloseCapabilities>,
362 ) -> Self {
363 self.did_close = did_close.into_option();
364 self
365 }
366
367 #[must_use]
369 pub fn did_save(mut self, did_save: impl IntoOption<NesDocumentDidSaveCapabilities>) -> Self {
370 self.did_save = did_save.into_option();
371 self
372 }
373
374 #[must_use]
376 pub fn did_focus(
377 mut self,
378 did_focus: impl IntoOption<NesDocumentDidFocusCapabilities>,
379 ) -> Self {
380 self.did_focus = did_focus.into_option();
381 self
382 }
383
384 #[must_use]
390 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
391 self.meta = meta.into_option();
392 self
393 }
394}
395
396#[serde_as]
398#[skip_serializing_none]
399#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
400#[serde(rename_all = "camelCase")]
401#[non_exhaustive]
402pub struct NesDocumentDidOpenCapabilities {
403 #[serde_as(deserialize_as = "DefaultOnError")]
409 #[schemars(extend("x-deserialize-default-on-error" = true))]
410 #[serde(default)]
411 #[serde(rename = "_meta")]
412 pub meta: Option<Meta>,
413}
414
415impl NesDocumentDidOpenCapabilities {
416 #[must_use]
418 pub fn new() -> Self {
419 Self::default()
420 }
421}
422
423#[serde_as]
425#[skip_serializing_none]
426#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
427#[serde(rename_all = "camelCase")]
428#[non_exhaustive]
429pub struct NesDocumentDidChangeCapabilities {
430 pub sync_kind: TextDocumentSyncKind,
432 #[serde_as(deserialize_as = "DefaultOnError")]
438 #[schemars(extend("x-deserialize-default-on-error" = true))]
439 #[serde(default)]
440 #[serde(rename = "_meta")]
441 pub meta: Option<Meta>,
442}
443
444impl NesDocumentDidChangeCapabilities {
445 #[must_use]
447 pub fn new(sync_kind: TextDocumentSyncKind) -> Self {
448 Self {
449 sync_kind,
450 meta: None,
451 }
452 }
453
454 #[must_use]
460 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
461 self.meta = meta.into_option();
462 self
463 }
464}
465
466#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
468#[non_exhaustive]
469pub enum TextDocumentSyncKind {
470 #[serde(rename = "full")]
472 Full,
473 #[serde(rename = "incremental")]
475 Incremental,
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 NesDocumentDidCloseCapabilities {
485 #[serde_as(deserialize_as = "DefaultOnError")]
491 #[schemars(extend("x-deserialize-default-on-error" = true))]
492 #[serde(default)]
493 #[serde(rename = "_meta")]
494 pub meta: Option<Meta>,
495}
496
497impl NesDocumentDidCloseCapabilities {
498 #[must_use]
500 pub fn new() -> Self {
501 Self::default()
502 }
503}
504
505#[serde_as]
507#[skip_serializing_none]
508#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
509#[serde(rename_all = "camelCase")]
510#[non_exhaustive]
511pub struct NesDocumentDidSaveCapabilities {
512 #[serde_as(deserialize_as = "DefaultOnError")]
518 #[schemars(extend("x-deserialize-default-on-error" = true))]
519 #[serde(default)]
520 #[serde(rename = "_meta")]
521 pub meta: Option<Meta>,
522}
523
524impl NesDocumentDidSaveCapabilities {
525 #[must_use]
527 pub fn new() -> Self {
528 Self::default()
529 }
530}
531
532#[serde_as]
534#[skip_serializing_none]
535#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
536#[serde(rename_all = "camelCase")]
537#[non_exhaustive]
538pub struct NesDocumentDidFocusCapabilities {
539 #[serde_as(deserialize_as = "DefaultOnError")]
545 #[schemars(extend("x-deserialize-default-on-error" = true))]
546 #[serde(default)]
547 #[serde(rename = "_meta")]
548 pub meta: Option<Meta>,
549}
550
551impl NesDocumentDidFocusCapabilities {
552 #[must_use]
554 pub fn new() -> Self {
555 Self::default()
556 }
557}
558
559#[serde_as]
561#[skip_serializing_none]
562#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
563#[serde(rename_all = "camelCase")]
564#[non_exhaustive]
565pub struct NesContextCapabilities {
566 #[serde_as(deserialize_as = "DefaultOnError")]
568 #[schemars(extend("x-deserialize-default-on-error" = true))]
569 #[serde(default)]
570 pub recent_files: Option<NesRecentFilesCapabilities>,
571 #[serde_as(deserialize_as = "DefaultOnError")]
573 #[schemars(extend("x-deserialize-default-on-error" = true))]
574 #[serde(default)]
575 pub related_snippets: Option<NesRelatedSnippetsCapabilities>,
576 #[serde_as(deserialize_as = "DefaultOnError")]
578 #[schemars(extend("x-deserialize-default-on-error" = true))]
579 #[serde(default)]
580 pub edit_history: Option<NesEditHistoryCapabilities>,
581 #[serde_as(deserialize_as = "DefaultOnError")]
583 #[schemars(extend("x-deserialize-default-on-error" = true))]
584 #[serde(default)]
585 pub user_actions: Option<NesUserActionsCapabilities>,
586 #[serde_as(deserialize_as = "DefaultOnError")]
588 #[schemars(extend("x-deserialize-default-on-error" = true))]
589 #[serde(default)]
590 pub open_files: Option<NesOpenFilesCapabilities>,
591 #[serde_as(deserialize_as = "DefaultOnError")]
593 #[schemars(extend("x-deserialize-default-on-error" = true))]
594 #[serde(default)]
595 pub diagnostics: Option<NesDiagnosticsCapabilities>,
596 #[serde_as(deserialize_as = "DefaultOnError")]
602 #[schemars(extend("x-deserialize-default-on-error" = true))]
603 #[serde(default)]
604 #[serde(rename = "_meta")]
605 pub meta: Option<Meta>,
606}
607
608impl NesContextCapabilities {
609 #[must_use]
611 pub fn new() -> Self {
612 Self::default()
613 }
614
615 #[must_use]
617 pub fn recent_files(
618 mut self,
619 recent_files: impl IntoOption<NesRecentFilesCapabilities>,
620 ) -> Self {
621 self.recent_files = recent_files.into_option();
622 self
623 }
624
625 #[must_use]
627 pub fn related_snippets(
628 mut self,
629 related_snippets: impl IntoOption<NesRelatedSnippetsCapabilities>,
630 ) -> Self {
631 self.related_snippets = related_snippets.into_option();
632 self
633 }
634
635 #[must_use]
637 pub fn edit_history(
638 mut self,
639 edit_history: impl IntoOption<NesEditHistoryCapabilities>,
640 ) -> Self {
641 self.edit_history = edit_history.into_option();
642 self
643 }
644
645 #[must_use]
647 pub fn user_actions(
648 mut self,
649 user_actions: impl IntoOption<NesUserActionsCapabilities>,
650 ) -> Self {
651 self.user_actions = user_actions.into_option();
652 self
653 }
654
655 #[must_use]
657 pub fn open_files(mut self, open_files: impl IntoOption<NesOpenFilesCapabilities>) -> Self {
658 self.open_files = open_files.into_option();
659 self
660 }
661
662 #[must_use]
664 pub fn diagnostics(mut self, diagnostics: impl IntoOption<NesDiagnosticsCapabilities>) -> Self {
665 self.diagnostics = diagnostics.into_option();
666 self
667 }
668
669 #[must_use]
675 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
676 self.meta = meta.into_option();
677 self
678 }
679}
680
681#[serde_as]
683#[skip_serializing_none]
684#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
685#[serde(rename_all = "camelCase")]
686#[non_exhaustive]
687pub struct NesRecentFilesCapabilities {
688 #[serde_as(deserialize_as = "DefaultOnError")]
690 #[schemars(extend("x-deserialize-default-on-error" = true))]
691 #[serde(default)]
692 pub max_count: Option<u32>,
693 #[serde_as(deserialize_as = "DefaultOnError")]
699 #[schemars(extend("x-deserialize-default-on-error" = true))]
700 #[serde(default)]
701 #[serde(rename = "_meta")]
702 pub meta: Option<Meta>,
703}
704
705impl NesRecentFilesCapabilities {
706 #[must_use]
708 pub fn new() -> Self {
709 Self::default()
710 }
711}
712
713#[serde_as]
715#[skip_serializing_none]
716#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
717#[serde(rename_all = "camelCase")]
718#[non_exhaustive]
719pub struct NesRelatedSnippetsCapabilities {
720 #[serde_as(deserialize_as = "DefaultOnError")]
726 #[schemars(extend("x-deserialize-default-on-error" = true))]
727 #[serde(default)]
728 #[serde(rename = "_meta")]
729 pub meta: Option<Meta>,
730}
731
732impl NesRelatedSnippetsCapabilities {
733 #[must_use]
735 pub fn new() -> Self {
736 Self::default()
737 }
738}
739
740#[serde_as]
742#[skip_serializing_none]
743#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
744#[serde(rename_all = "camelCase")]
745#[non_exhaustive]
746pub struct NesEditHistoryCapabilities {
747 #[serde_as(deserialize_as = "DefaultOnError")]
749 #[schemars(extend("x-deserialize-default-on-error" = true))]
750 #[serde(default)]
751 pub max_count: Option<u32>,
752 #[serde_as(deserialize_as = "DefaultOnError")]
758 #[schemars(extend("x-deserialize-default-on-error" = true))]
759 #[serde(default)]
760 #[serde(rename = "_meta")]
761 pub meta: Option<Meta>,
762}
763
764impl NesEditHistoryCapabilities {
765 #[must_use]
767 pub fn new() -> Self {
768 Self::default()
769 }
770}
771
772#[serde_as]
774#[skip_serializing_none]
775#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
776#[serde(rename_all = "camelCase")]
777#[non_exhaustive]
778pub struct NesUserActionsCapabilities {
779 #[serde_as(deserialize_as = "DefaultOnError")]
781 #[schemars(extend("x-deserialize-default-on-error" = true))]
782 #[serde(default)]
783 pub max_count: Option<u32>,
784 #[serde_as(deserialize_as = "DefaultOnError")]
790 #[schemars(extend("x-deserialize-default-on-error" = true))]
791 #[serde(default)]
792 #[serde(rename = "_meta")]
793 pub meta: Option<Meta>,
794}
795
796impl NesUserActionsCapabilities {
797 #[must_use]
799 pub fn new() -> Self {
800 Self::default()
801 }
802}
803
804#[serde_as]
806#[skip_serializing_none]
807#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
808#[serde(rename_all = "camelCase")]
809#[non_exhaustive]
810pub struct NesOpenFilesCapabilities {
811 #[serde_as(deserialize_as = "DefaultOnError")]
817 #[schemars(extend("x-deserialize-default-on-error" = true))]
818 #[serde(default)]
819 #[serde(rename = "_meta")]
820 pub meta: Option<Meta>,
821}
822
823impl NesOpenFilesCapabilities {
824 #[must_use]
826 pub fn new() -> Self {
827 Self::default()
828 }
829}
830
831#[serde_as]
833#[skip_serializing_none]
834#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
835#[serde(rename_all = "camelCase")]
836#[non_exhaustive]
837pub struct NesDiagnosticsCapabilities {
838 #[serde_as(deserialize_as = "DefaultOnError")]
844 #[schemars(extend("x-deserialize-default-on-error" = true))]
845 #[serde(default)]
846 #[serde(rename = "_meta")]
847 pub meta: Option<Meta>,
848}
849
850impl NesDiagnosticsCapabilities {
851 #[must_use]
853 pub fn new() -> Self {
854 Self::default()
855 }
856}
857
858#[serde_as]
862#[skip_serializing_none]
863#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
864#[serde(rename_all = "camelCase")]
865#[non_exhaustive]
866pub struct ClientNesCapabilities {
867 #[serde_as(deserialize_as = "DefaultOnError")]
869 #[schemars(extend("x-deserialize-default-on-error" = true))]
870 #[serde(default)]
871 pub jump: Option<NesJumpCapabilities>,
872 #[serde_as(deserialize_as = "DefaultOnError")]
874 #[schemars(extend("x-deserialize-default-on-error" = true))]
875 #[serde(default)]
876 pub rename: Option<NesRenameCapabilities>,
877 #[serde_as(deserialize_as = "DefaultOnError")]
879 #[schemars(extend("x-deserialize-default-on-error" = true))]
880 #[serde(default)]
881 pub search_and_replace: Option<NesSearchAndReplaceCapabilities>,
882 #[serde_as(deserialize_as = "DefaultOnError")]
888 #[schemars(extend("x-deserialize-default-on-error" = true))]
889 #[serde(default)]
890 #[serde(rename = "_meta")]
891 pub meta: Option<Meta>,
892}
893
894impl ClientNesCapabilities {
895 #[must_use]
897 pub fn new() -> Self {
898 Self::default()
899 }
900
901 #[must_use]
903 pub fn jump(mut self, jump: impl IntoOption<NesJumpCapabilities>) -> Self {
904 self.jump = jump.into_option();
905 self
906 }
907
908 #[must_use]
910 pub fn rename(mut self, rename: impl IntoOption<NesRenameCapabilities>) -> Self {
911 self.rename = rename.into_option();
912 self
913 }
914
915 #[must_use]
917 pub fn search_and_replace(
918 mut self,
919 search_and_replace: impl IntoOption<NesSearchAndReplaceCapabilities>,
920 ) -> Self {
921 self.search_and_replace = search_and_replace.into_option();
922 self
923 }
924
925 #[must_use]
931 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
932 self.meta = meta.into_option();
933 self
934 }
935}
936
937#[serde_as]
939#[skip_serializing_none]
940#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
941#[serde(rename_all = "camelCase")]
942#[non_exhaustive]
943pub struct NesJumpCapabilities {
944 #[serde_as(deserialize_as = "DefaultOnError")]
950 #[schemars(extend("x-deserialize-default-on-error" = true))]
951 #[serde(default)]
952 #[serde(rename = "_meta")]
953 pub meta: Option<Meta>,
954}
955
956impl NesJumpCapabilities {
957 #[must_use]
959 pub fn new() -> Self {
960 Self::default()
961 }
962}
963
964#[serde_as]
966#[skip_serializing_none]
967#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
968#[serde(rename_all = "camelCase")]
969#[non_exhaustive]
970pub struct NesRenameCapabilities {
971 #[serde_as(deserialize_as = "DefaultOnError")]
977 #[schemars(extend("x-deserialize-default-on-error" = true))]
978 #[serde(default)]
979 #[serde(rename = "_meta")]
980 pub meta: Option<Meta>,
981}
982
983impl NesRenameCapabilities {
984 #[must_use]
986 pub fn new() -> Self {
987 Self::default()
988 }
989}
990
991#[serde_as]
993#[skip_serializing_none]
994#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
995#[serde(rename_all = "camelCase")]
996#[non_exhaustive]
997pub struct NesSearchAndReplaceCapabilities {
998 #[serde_as(deserialize_as = "DefaultOnError")]
1004 #[schemars(extend("x-deserialize-default-on-error" = true))]
1005 #[serde(default)]
1006 #[serde(rename = "_meta")]
1007 pub meta: Option<Meta>,
1008}
1009
1010impl NesSearchAndReplaceCapabilities {
1011 #[must_use]
1013 pub fn new() -> Self {
1014 Self::default()
1015 }
1016}
1017
1018#[serde_as]
1022#[skip_serializing_none]
1023#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1024#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_OPEN_METHOD_NAME))]
1025#[serde(rename_all = "camelCase")]
1026#[non_exhaustive]
1027pub struct DidOpenDocumentNotification {
1028 pub session_id: SessionId,
1030 #[schemars(url)]
1032 pub uri: String,
1033 pub language_id: String,
1035 pub version: i64,
1037 pub text: String,
1039 #[serde_as(deserialize_as = "DefaultOnError")]
1045 #[schemars(extend("x-deserialize-default-on-error" = true))]
1046 #[serde(default)]
1047 #[serde(rename = "_meta")]
1048 pub meta: Option<Meta>,
1049}
1050
1051impl DidOpenDocumentNotification {
1052 #[must_use]
1054 pub fn new(
1055 session_id: impl Into<SessionId>,
1056 uri: impl Into<String>,
1057 language_id: impl Into<String>,
1058 version: i64,
1059 text: impl Into<String>,
1060 ) -> Self {
1061 Self {
1062 session_id: session_id.into(),
1063 uri: uri.into(),
1064 language_id: language_id.into(),
1065 version,
1066 text: text.into(),
1067 meta: None,
1068 }
1069 }
1070
1071 #[must_use]
1077 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1078 self.meta = meta.into_option();
1079 self
1080 }
1081}
1082
1083#[serde_as]
1085#[skip_serializing_none]
1086#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1087#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_CHANGE_METHOD_NAME))]
1088#[serde(rename_all = "camelCase")]
1089#[non_exhaustive]
1090pub struct DidChangeDocumentNotification {
1091 pub session_id: SessionId,
1093 #[schemars(url)]
1095 pub uri: String,
1096 pub version: i64,
1098 #[serde_as(deserialize_as = "DefaultOnError<VecSkipError<_, SkipListener>>")]
1100 #[schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true))]
1101 pub content_changes: Vec<TextDocumentContentChangeEvent>,
1102 #[serde_as(deserialize_as = "DefaultOnError")]
1108 #[schemars(extend("x-deserialize-default-on-error" = true))]
1109 #[serde(default)]
1110 #[serde(rename = "_meta")]
1111 pub meta: Option<Meta>,
1112}
1113
1114impl DidChangeDocumentNotification {
1115 #[must_use]
1117 pub fn new(
1118 session_id: impl Into<SessionId>,
1119 uri: impl Into<String>,
1120 version: i64,
1121 content_changes: Vec<TextDocumentContentChangeEvent>,
1122 ) -> Self {
1123 Self {
1124 session_id: session_id.into(),
1125 uri: uri.into(),
1126 version,
1127 content_changes,
1128 meta: None,
1129 }
1130 }
1131
1132 #[must_use]
1138 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1139 self.meta = meta.into_option();
1140 self
1141 }
1142}
1143
1144#[serde_as]
1149#[skip_serializing_none]
1150#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1151#[serde(rename_all = "camelCase")]
1152#[non_exhaustive]
1153pub struct TextDocumentContentChangeEvent {
1154 #[serde(default)]
1156 pub range: Option<Range>,
1157 pub text: String,
1159 #[serde_as(deserialize_as = "DefaultOnError")]
1165 #[schemars(extend("x-deserialize-default-on-error" = true))]
1166 #[serde(default)]
1167 #[serde(rename = "_meta")]
1168 pub meta: Option<Meta>,
1169}
1170
1171impl TextDocumentContentChangeEvent {
1172 #[must_use]
1174 pub fn full(text: impl Into<String>) -> Self {
1175 Self {
1176 range: None,
1177 text: text.into(),
1178 meta: None,
1179 }
1180 }
1181
1182 #[must_use]
1184 pub fn incremental(range: Range, text: impl Into<String>) -> Self {
1185 Self {
1186 range: Some(range),
1187 text: text.into(),
1188 meta: None,
1189 }
1190 }
1191
1192 #[must_use]
1198 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1199 self.meta = meta.into_option();
1200 self
1201 }
1202}
1203
1204#[serde_as]
1206#[skip_serializing_none]
1207#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1208#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_CLOSE_METHOD_NAME))]
1209#[serde(rename_all = "camelCase")]
1210#[non_exhaustive]
1211pub struct DidCloseDocumentNotification {
1212 pub session_id: SessionId,
1214 #[schemars(url)]
1216 pub uri: String,
1217 #[serde_as(deserialize_as = "DefaultOnError")]
1223 #[schemars(extend("x-deserialize-default-on-error" = true))]
1224 #[serde(default)]
1225 #[serde(rename = "_meta")]
1226 pub meta: Option<Meta>,
1227}
1228
1229impl DidCloseDocumentNotification {
1230 #[must_use]
1232 pub fn new(session_id: impl Into<SessionId>, uri: impl Into<String>) -> Self {
1233 Self {
1234 session_id: session_id.into(),
1235 uri: uri.into(),
1236 meta: None,
1237 }
1238 }
1239
1240 #[must_use]
1246 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1247 self.meta = meta.into_option();
1248 self
1249 }
1250}
1251
1252#[serde_as]
1254#[skip_serializing_none]
1255#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1256#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_SAVE_METHOD_NAME))]
1257#[serde(rename_all = "camelCase")]
1258#[non_exhaustive]
1259pub struct DidSaveDocumentNotification {
1260 pub session_id: SessionId,
1262 #[schemars(url)]
1264 pub uri: String,
1265 #[serde_as(deserialize_as = "DefaultOnError")]
1271 #[schemars(extend("x-deserialize-default-on-error" = true))]
1272 #[serde(default)]
1273 #[serde(rename = "_meta")]
1274 pub meta: Option<Meta>,
1275}
1276
1277impl DidSaveDocumentNotification {
1278 #[must_use]
1280 pub fn new(session_id: impl Into<SessionId>, uri: impl Into<String>) -> Self {
1281 Self {
1282 session_id: session_id.into(),
1283 uri: uri.into(),
1284 meta: None,
1285 }
1286 }
1287
1288 #[must_use]
1294 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1295 self.meta = meta.into_option();
1296 self
1297 }
1298}
1299
1300#[serde_as]
1302#[skip_serializing_none]
1303#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1304#[schemars(extend("x-side" = "agent", "x-method" = DOCUMENT_DID_FOCUS_METHOD_NAME))]
1305#[serde(rename_all = "camelCase")]
1306#[non_exhaustive]
1307pub struct DidFocusDocumentNotification {
1308 pub session_id: SessionId,
1310 #[schemars(url)]
1312 pub uri: String,
1313 pub version: i64,
1315 pub position: Position,
1317 pub visible_range: Range,
1319 #[serde_as(deserialize_as = "DefaultOnError")]
1325 #[schemars(extend("x-deserialize-default-on-error" = true))]
1326 #[serde(default)]
1327 #[serde(rename = "_meta")]
1328 pub meta: Option<Meta>,
1329}
1330
1331impl DidFocusDocumentNotification {
1332 #[must_use]
1334 pub fn new(
1335 session_id: impl Into<SessionId>,
1336 uri: impl Into<String>,
1337 version: i64,
1338 position: Position,
1339 visible_range: Range,
1340 ) -> Self {
1341 Self {
1342 session_id: session_id.into(),
1343 uri: uri.into(),
1344 version,
1345 position,
1346 visible_range,
1347 meta: None,
1348 }
1349 }
1350
1351 #[must_use]
1357 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1358 self.meta = meta.into_option();
1359 self
1360 }
1361}
1362
1363#[serde_as]
1367#[skip_serializing_none]
1368#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1369#[schemars(extend("x-side" = "agent", "x-method" = NES_START_METHOD_NAME))]
1370#[serde(rename_all = "camelCase")]
1371#[non_exhaustive]
1372pub struct StartNesRequest {
1373 #[serde_as(deserialize_as = "DefaultOnError")]
1375 #[schemars(extend("x-deserialize-default-on-error" = true))]
1376 #[schemars(url)]
1377 #[serde(default)]
1378 pub workspace_uri: Option<String>,
1379 #[serde(default)]
1381 pub workspace_folders: Option<Vec<WorkspaceFolder>>,
1382 #[serde_as(deserialize_as = "DefaultOnError")]
1384 #[schemars(extend("x-deserialize-default-on-error" = true))]
1385 #[serde(default)]
1386 pub repository: Option<NesRepository>,
1387 #[serde_as(deserialize_as = "DefaultOnError")]
1393 #[schemars(extend("x-deserialize-default-on-error" = true))]
1394 #[serde(default)]
1395 #[serde(rename = "_meta")]
1396 pub meta: Option<Meta>,
1397}
1398
1399impl StartNesRequest {
1400 #[must_use]
1402 pub fn new() -> Self {
1403 Self {
1404 workspace_uri: None,
1405 workspace_folders: None,
1406 repository: None,
1407 meta: None,
1408 }
1409 }
1410
1411 #[must_use]
1413 pub fn workspace_uri(mut self, workspace_uri: impl IntoOption<String>) -> Self {
1414 self.workspace_uri = workspace_uri.into_option();
1415 self
1416 }
1417
1418 #[must_use]
1420 pub fn workspace_folders(
1421 mut self,
1422 workspace_folders: impl IntoOption<Vec<WorkspaceFolder>>,
1423 ) -> Self {
1424 self.workspace_folders = workspace_folders.into_option();
1425 self
1426 }
1427
1428 #[must_use]
1430 pub fn repository(mut self, repository: impl IntoOption<NesRepository>) -> Self {
1431 self.repository = repository.into_option();
1432 self
1433 }
1434
1435 #[must_use]
1441 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1442 self.meta = meta.into_option();
1443 self
1444 }
1445}
1446
1447impl Default for StartNesRequest {
1448 fn default() -> Self {
1449 Self::new()
1450 }
1451}
1452
1453#[serde_as]
1455#[skip_serializing_none]
1456#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1457#[serde(rename_all = "camelCase")]
1458#[non_exhaustive]
1459pub struct WorkspaceFolder {
1460 #[schemars(url)]
1462 pub uri: String,
1463 pub name: String,
1465 #[serde_as(deserialize_as = "DefaultOnError")]
1471 #[schemars(extend("x-deserialize-default-on-error" = true))]
1472 #[serde(default)]
1473 #[serde(rename = "_meta")]
1474 pub meta: Option<Meta>,
1475}
1476
1477impl WorkspaceFolder {
1478 #[must_use]
1480 pub fn new(uri: impl Into<String>, name: impl Into<String>) -> Self {
1481 Self {
1482 uri: uri.into(),
1483 name: name.into(),
1484 meta: None,
1485 }
1486 }
1487
1488 #[must_use]
1494 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1495 self.meta = meta.into_option();
1496 self
1497 }
1498}
1499
1500#[serde_as]
1502#[skip_serializing_none]
1503#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1504#[serde(rename_all = "camelCase")]
1505#[non_exhaustive]
1506pub struct NesRepository {
1507 pub name: String,
1509 pub owner: String,
1511 pub remote_url: String,
1513 #[serde_as(deserialize_as = "DefaultOnError")]
1519 #[schemars(extend("x-deserialize-default-on-error" = true))]
1520 #[serde(default)]
1521 #[serde(rename = "_meta")]
1522 pub meta: Option<Meta>,
1523}
1524
1525impl NesRepository {
1526 #[must_use]
1528 pub fn new(
1529 name: impl Into<String>,
1530 owner: impl Into<String>,
1531 remote_url: impl Into<String>,
1532 ) -> Self {
1533 Self {
1534 name: name.into(),
1535 owner: owner.into(),
1536 remote_url: remote_url.into(),
1537 meta: None,
1538 }
1539 }
1540
1541 #[must_use]
1547 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1548 self.meta = meta.into_option();
1549 self
1550 }
1551}
1552
1553#[serde_as]
1555#[skip_serializing_none]
1556#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1557#[schemars(extend("x-side" = "agent", "x-method" = NES_START_METHOD_NAME))]
1558#[serde(rename_all = "camelCase")]
1559#[non_exhaustive]
1560pub struct StartNesResponse {
1561 pub session_id: SessionId,
1563 #[serde_as(deserialize_as = "DefaultOnError")]
1569 #[schemars(extend("x-deserialize-default-on-error" = true))]
1570 #[serde(default)]
1571 #[serde(rename = "_meta")]
1572 pub meta: Option<Meta>,
1573}
1574
1575impl StartNesResponse {
1576 #[must_use]
1578 pub fn new(session_id: impl Into<SessionId>) -> Self {
1579 Self {
1580 session_id: session_id.into(),
1581 meta: None,
1582 }
1583 }
1584
1585 #[must_use]
1591 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1592 self.meta = meta.into_option();
1593 self
1594 }
1595}
1596
1597#[serde_as]
1604#[skip_serializing_none]
1605#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1606#[schemars(extend("x-side" = "agent", "x-method" = NES_CLOSE_METHOD_NAME))]
1607#[serde(rename_all = "camelCase")]
1608#[non_exhaustive]
1609pub struct CloseNesRequest {
1610 pub session_id: SessionId,
1612 #[serde_as(deserialize_as = "DefaultOnError")]
1618 #[schemars(extend("x-deserialize-default-on-error" = true))]
1619 #[serde(default)]
1620 #[serde(rename = "_meta")]
1621 pub meta: Option<Meta>,
1622}
1623
1624impl CloseNesRequest {
1625 #[must_use]
1627 pub fn new(session_id: impl Into<SessionId>) -> Self {
1628 Self {
1629 session_id: session_id.into(),
1630 meta: None,
1631 }
1632 }
1633
1634 #[must_use]
1640 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1641 self.meta = meta.into_option();
1642 self
1643 }
1644}
1645
1646#[serde_as]
1648#[skip_serializing_none]
1649#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1650#[schemars(extend("x-side" = "agent", "x-method" = NES_CLOSE_METHOD_NAME))]
1651#[serde(rename_all = "camelCase")]
1652#[non_exhaustive]
1653pub struct CloseNesResponse {
1654 #[serde_as(deserialize_as = "DefaultOnError")]
1660 #[schemars(extend("x-deserialize-default-on-error" = true))]
1661 #[serde(default)]
1662 #[serde(rename = "_meta")]
1663 pub meta: Option<Meta>,
1664}
1665
1666impl CloseNesResponse {
1667 #[must_use]
1669 pub fn new() -> Self {
1670 Self::default()
1671 }
1672
1673 #[must_use]
1679 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1680 self.meta = meta.into_option();
1681 self
1682 }
1683}
1684
1685#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1689#[non_exhaustive]
1690pub enum NesTriggerKind {
1691 #[serde(rename = "automatic")]
1693 Automatic,
1694 #[serde(rename = "diagnostic")]
1696 Diagnostic,
1697 #[serde(rename = "manual")]
1699 Manual,
1700 #[serde(untagged)]
1706 Other(String),
1707}
1708
1709#[serde_as]
1711#[skip_serializing_none]
1712#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1713#[schemars(extend("x-side" = "agent", "x-method" = NES_SUGGEST_METHOD_NAME))]
1714#[serde(rename_all = "camelCase")]
1715#[non_exhaustive]
1716pub struct SuggestNesRequest {
1717 pub session_id: SessionId,
1719 #[schemars(url)]
1721 pub uri: String,
1722 pub version: i64,
1724 pub position: Position,
1726 #[serde(default)]
1728 pub selection: Option<Range>,
1729 pub trigger_kind: NesTriggerKind,
1731 #[serde(default)]
1733 pub context: Option<NesSuggestContext>,
1734 #[serde_as(deserialize_as = "DefaultOnError")]
1740 #[schemars(extend("x-deserialize-default-on-error" = true))]
1741 #[serde(default)]
1742 #[serde(rename = "_meta")]
1743 pub meta: Option<Meta>,
1744}
1745
1746impl SuggestNesRequest {
1747 #[must_use]
1749 pub fn new(
1750 session_id: impl Into<SessionId>,
1751 uri: impl Into<String>,
1752 version: i64,
1753 position: Position,
1754 trigger_kind: NesTriggerKind,
1755 ) -> Self {
1756 Self {
1757 session_id: session_id.into(),
1758 uri: uri.into(),
1759 version,
1760 position,
1761 selection: None,
1762 trigger_kind,
1763 context: None,
1764 meta: None,
1765 }
1766 }
1767
1768 #[must_use]
1770 pub fn selection(mut self, selection: impl IntoOption<Range>) -> Self {
1771 self.selection = selection.into_option();
1772 self
1773 }
1774
1775 #[must_use]
1777 pub fn context(mut self, context: impl IntoOption<NesSuggestContext>) -> Self {
1778 self.context = context.into_option();
1779 self
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#[serde_as]
1796#[skip_serializing_none]
1797#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1798#[serde(rename_all = "camelCase")]
1799#[non_exhaustive]
1800pub struct NesSuggestContext {
1801 #[serde(default)]
1803 pub recent_files: Option<Vec<NesRecentFile>>,
1804 #[serde(default)]
1806 pub related_snippets: Option<Vec<NesRelatedSnippet>>,
1807 #[serde(default)]
1809 pub edit_history: Option<Vec<NesEditHistoryEntry>>,
1810 #[serde(default)]
1812 pub user_actions: Option<Vec<NesUserAction>>,
1813 #[serde(default)]
1815 pub open_files: Option<Vec<NesOpenFile>>,
1816 #[serde(default)]
1818 pub diagnostics: Option<Vec<NesDiagnostic>>,
1819 #[serde_as(deserialize_as = "DefaultOnError")]
1825 #[schemars(extend("x-deserialize-default-on-error" = true))]
1826 #[serde(default)]
1827 #[serde(rename = "_meta")]
1828 pub meta: Option<Meta>,
1829}
1830
1831impl NesSuggestContext {
1832 #[must_use]
1834 pub fn new() -> Self {
1835 Self::default()
1836 }
1837
1838 #[must_use]
1840 pub fn recent_files(mut self, recent_files: impl IntoOption<Vec<NesRecentFile>>) -> Self {
1841 self.recent_files = recent_files.into_option();
1842 self
1843 }
1844
1845 #[must_use]
1847 pub fn related_snippets(
1848 mut self,
1849 related_snippets: impl IntoOption<Vec<NesRelatedSnippet>>,
1850 ) -> Self {
1851 self.related_snippets = related_snippets.into_option();
1852 self
1853 }
1854
1855 #[must_use]
1857 pub fn edit_history(mut self, edit_history: impl IntoOption<Vec<NesEditHistoryEntry>>) -> Self {
1858 self.edit_history = edit_history.into_option();
1859 self
1860 }
1861
1862 #[must_use]
1864 pub fn user_actions(mut self, user_actions: impl IntoOption<Vec<NesUserAction>>) -> Self {
1865 self.user_actions = user_actions.into_option();
1866 self
1867 }
1868
1869 #[must_use]
1871 pub fn open_files(mut self, open_files: impl IntoOption<Vec<NesOpenFile>>) -> Self {
1872 self.open_files = open_files.into_option();
1873 self
1874 }
1875
1876 #[must_use]
1878 pub fn diagnostics(mut self, diagnostics: impl IntoOption<Vec<NesDiagnostic>>) -> Self {
1879 self.diagnostics = diagnostics.into_option();
1880 self
1881 }
1882
1883 #[must_use]
1889 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1890 self.meta = meta.into_option();
1891 self
1892 }
1893}
1894
1895#[serde_as]
1897#[skip_serializing_none]
1898#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1899#[serde(rename_all = "camelCase")]
1900#[non_exhaustive]
1901pub struct NesRecentFile {
1902 #[schemars(url)]
1904 pub uri: String,
1905 pub language_id: String,
1907 pub text: String,
1909 #[serde_as(deserialize_as = "DefaultOnError")]
1915 #[schemars(extend("x-deserialize-default-on-error" = true))]
1916 #[serde(default)]
1917 #[serde(rename = "_meta")]
1918 pub meta: Option<Meta>,
1919}
1920
1921impl NesRecentFile {
1922 #[must_use]
1924 pub fn new(
1925 uri: impl Into<String>,
1926 language_id: impl Into<String>,
1927 text: impl Into<String>,
1928 ) -> Self {
1929 Self {
1930 uri: uri.into(),
1931 language_id: language_id.into(),
1932 text: text.into(),
1933 meta: None,
1934 }
1935 }
1936
1937 #[must_use]
1943 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1944 self.meta = meta.into_option();
1945 self
1946 }
1947}
1948
1949#[serde_as]
1951#[skip_serializing_none]
1952#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1953#[serde(rename_all = "camelCase")]
1954#[non_exhaustive]
1955pub struct NesRelatedSnippet {
1956 #[schemars(url)]
1958 pub uri: String,
1959 pub excerpts: Vec<NesExcerpt>,
1961 #[serde_as(deserialize_as = "DefaultOnError")]
1967 #[schemars(extend("x-deserialize-default-on-error" = true))]
1968 #[serde(default)]
1969 #[serde(rename = "_meta")]
1970 pub meta: Option<Meta>,
1971}
1972
1973impl NesRelatedSnippet {
1974 #[must_use]
1976 pub fn new(uri: impl Into<String>, excerpts: Vec<NesExcerpt>) -> Self {
1977 Self {
1978 uri: uri.into(),
1979 excerpts,
1980 meta: None,
1981 }
1982 }
1983
1984 #[must_use]
1990 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
1991 self.meta = meta.into_option();
1992 self
1993 }
1994}
1995
1996#[serde_as]
1998#[skip_serializing_none]
1999#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2000#[serde(rename_all = "camelCase")]
2001#[non_exhaustive]
2002pub struct NesExcerpt {
2003 pub start_line: u32,
2005 pub end_line: u32,
2007 pub text: String,
2009 #[serde_as(deserialize_as = "DefaultOnError")]
2015 #[schemars(extend("x-deserialize-default-on-error" = true))]
2016 #[serde(default)]
2017 #[serde(rename = "_meta")]
2018 pub meta: Option<Meta>,
2019}
2020
2021impl NesExcerpt {
2022 #[must_use]
2024 pub fn new(start_line: u32, end_line: u32, text: impl Into<String>) -> Self {
2025 Self {
2026 start_line,
2027 end_line,
2028 text: text.into(),
2029 meta: None,
2030 }
2031 }
2032
2033 #[must_use]
2039 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2040 self.meta = meta.into_option();
2041 self
2042 }
2043}
2044
2045#[serde_as]
2047#[skip_serializing_none]
2048#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2049#[serde(rename_all = "camelCase")]
2050#[non_exhaustive]
2051pub struct NesEditHistoryEntry {
2052 #[schemars(url)]
2054 pub uri: String,
2055 pub diff: String,
2057 #[serde_as(deserialize_as = "DefaultOnError")]
2063 #[schemars(extend("x-deserialize-default-on-error" = true))]
2064 #[serde(default)]
2065 #[serde(rename = "_meta")]
2066 pub meta: Option<Meta>,
2067}
2068
2069impl NesEditHistoryEntry {
2070 #[must_use]
2072 pub fn new(uri: impl Into<String>, diff: impl Into<String>) -> Self {
2073 Self {
2074 uri: uri.into(),
2075 diff: diff.into(),
2076 meta: None,
2077 }
2078 }
2079
2080 #[must_use]
2086 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2087 self.meta = meta.into_option();
2088 self
2089 }
2090}
2091
2092#[serde_as]
2094#[skip_serializing_none]
2095#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2096#[serde(rename_all = "camelCase")]
2097#[non_exhaustive]
2098pub struct NesUserAction {
2099 pub action: String,
2101 #[schemars(url)]
2103 pub uri: String,
2104 pub position: Position,
2106 pub timestamp_ms: u64,
2108 #[serde_as(deserialize_as = "DefaultOnError")]
2114 #[schemars(extend("x-deserialize-default-on-error" = true))]
2115 #[serde(default)]
2116 #[serde(rename = "_meta")]
2117 pub meta: Option<Meta>,
2118}
2119
2120impl NesUserAction {
2121 #[must_use]
2123 pub fn new(
2124 action: impl Into<String>,
2125 uri: impl Into<String>,
2126 position: Position,
2127 timestamp_ms: u64,
2128 ) -> Self {
2129 Self {
2130 action: action.into(),
2131 uri: uri.into(),
2132 position,
2133 timestamp_ms,
2134 meta: None,
2135 }
2136 }
2137
2138 #[must_use]
2144 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2145 self.meta = meta.into_option();
2146 self
2147 }
2148}
2149
2150#[serde_as]
2152#[skip_serializing_none]
2153#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2154#[serde(rename_all = "camelCase")]
2155#[non_exhaustive]
2156pub struct NesOpenFile {
2157 #[schemars(url)]
2159 pub uri: String,
2160 pub language_id: String,
2162 #[serde_as(deserialize_as = "DefaultOnError")]
2164 #[schemars(extend("x-deserialize-default-on-error" = true))]
2165 #[serde(default)]
2166 pub visible_range: Option<Range>,
2167 #[serde_as(deserialize_as = "DefaultOnError")]
2169 #[schemars(extend("x-deserialize-default-on-error" = true))]
2170 #[serde(default)]
2171 pub last_focused_ms: Option<u64>,
2172 #[serde_as(deserialize_as = "DefaultOnError")]
2178 #[schemars(extend("x-deserialize-default-on-error" = true))]
2179 #[serde(default)]
2180 #[serde(rename = "_meta")]
2181 pub meta: Option<Meta>,
2182}
2183
2184impl NesOpenFile {
2185 #[must_use]
2187 pub fn new(uri: impl Into<String>, language_id: impl Into<String>) -> Self {
2188 Self {
2189 uri: uri.into(),
2190 language_id: language_id.into(),
2191 visible_range: None,
2192 last_focused_ms: None,
2193 meta: None,
2194 }
2195 }
2196
2197 #[must_use]
2199 pub fn visible_range(mut self, visible_range: impl IntoOption<Range>) -> Self {
2200 self.visible_range = visible_range.into_option();
2201 self
2202 }
2203
2204 #[must_use]
2206 pub fn last_focused_ms(mut self, last_focused_ms: impl IntoOption<u64>) -> Self {
2207 self.last_focused_ms = last_focused_ms.into_option();
2208 self
2209 }
2210
2211 #[must_use]
2217 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2218 self.meta = meta.into_option();
2219 self
2220 }
2221}
2222
2223#[serde_as]
2225#[skip_serializing_none]
2226#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2227#[serde(rename_all = "camelCase")]
2228#[non_exhaustive]
2229pub struct NesDiagnostic {
2230 #[schemars(url)]
2232 pub uri: String,
2233 pub range: Range,
2235 pub severity: NesDiagnosticSeverity,
2237 pub message: String,
2239 #[serde_as(deserialize_as = "DefaultOnError")]
2245 #[schemars(extend("x-deserialize-default-on-error" = true))]
2246 #[serde(default)]
2247 #[serde(rename = "_meta")]
2248 pub meta: Option<Meta>,
2249}
2250
2251impl NesDiagnostic {
2252 #[must_use]
2254 pub fn new(
2255 uri: impl Into<String>,
2256 range: Range,
2257 severity: NesDiagnosticSeverity,
2258 message: impl Into<String>,
2259 ) -> Self {
2260 Self {
2261 uri: uri.into(),
2262 range,
2263 severity,
2264 message: message.into(),
2265 meta: None,
2266 }
2267 }
2268
2269 #[must_use]
2275 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2276 self.meta = meta.into_option();
2277 self
2278 }
2279}
2280
2281#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2283#[non_exhaustive]
2284pub enum NesDiagnosticSeverity {
2285 #[serde(rename = "error")]
2287 Error,
2288 #[serde(rename = "warning")]
2290 Warning,
2291 #[serde(rename = "information")]
2293 Information,
2294 #[serde(rename = "hint")]
2296 Hint,
2297 #[serde(untagged)]
2303 Other(String),
2304}
2305
2306#[serde_as]
2310#[skip_serializing_none]
2311#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2312#[schemars(extend("x-side" = "agent", "x-method" = NES_SUGGEST_METHOD_NAME))]
2313#[serde(rename_all = "camelCase")]
2314#[non_exhaustive]
2315pub struct SuggestNesResponse {
2316 pub suggestions: Vec<NesSuggestion>,
2318 #[serde_as(deserialize_as = "DefaultOnError")]
2324 #[schemars(extend("x-deserialize-default-on-error" = true))]
2325 #[serde(default)]
2326 #[serde(rename = "_meta")]
2327 pub meta: Option<Meta>,
2328}
2329
2330impl SuggestNesResponse {
2331 #[must_use]
2333 pub fn new(suggestions: Vec<NesSuggestion>) -> Self {
2334 Self {
2335 suggestions,
2336 meta: None,
2337 }
2338 }
2339
2340 #[must_use]
2346 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2347 self.meta = meta.into_option();
2348 self
2349 }
2350}
2351
2352#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2354#[serde(tag = "kind", rename_all = "camelCase")]
2355#[non_exhaustive]
2356pub enum NesSuggestion {
2357 Edit(NesEditSuggestion),
2359 Jump(NesJumpSuggestion),
2361 Rename(NesRenameSuggestion),
2363 SearchAndReplace(NesSearchAndReplaceSuggestion),
2365 #[serde(untagged)]
2375 Other(OtherNesSuggestion),
2376}
2377
2378#[derive(Debug, Clone, Serialize, JsonSchema, PartialEq, Eq)]
2380#[schemars(inline)]
2381#[schemars(transform = other_nes_suggestion_schema)]
2382#[serde(rename_all = "camelCase")]
2383#[non_exhaustive]
2384pub struct OtherNesSuggestion {
2385 pub kind: String,
2391 pub suggestion_id: NesSuggestionId,
2393 #[serde(flatten)]
2395 pub fields: BTreeMap<String, serde_json::Value>,
2396}
2397
2398impl OtherNesSuggestion {
2399 #[must_use]
2401 pub fn new(
2402 kind: impl Into<String>,
2403 suggestion_id: impl Into<NesSuggestionId>,
2404 mut fields: BTreeMap<String, serde_json::Value>,
2405 ) -> Self {
2406 fields.remove("kind");
2407 fields.remove("suggestionId");
2408 Self {
2409 kind: kind.into(),
2410 suggestion_id: suggestion_id.into(),
2411 fields,
2412 }
2413 }
2414}
2415
2416impl<'de> Deserialize<'de> for OtherNesSuggestion {
2417 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
2418 where
2419 D: serde::Deserializer<'de>,
2420 {
2421 let mut fields = BTreeMap::<String, serde_json::Value>::deserialize(deserializer)?;
2422 let kind = fields
2423 .remove("kind")
2424 .ok_or_else(|| serde::de::Error::missing_field("kind"))?;
2425 let serde_json::Value::String(kind) = kind else {
2426 return Err(serde::de::Error::custom("`kind` must be a string"));
2427 };
2428 let suggestion_id = fields
2429 .remove("suggestionId")
2430 .ok_or_else(|| serde::de::Error::missing_field("suggestionId"))?;
2431 let serde_json::Value::String(suggestion_id) = suggestion_id else {
2432 return Err(serde::de::Error::custom("`suggestionId` must be a string"));
2433 };
2434
2435 if is_known_nes_suggestion_kind(&kind) {
2436 return Err(serde::de::Error::custom(format!(
2437 "known NES suggestion `{kind}` did not match its schema"
2438 )));
2439 }
2440
2441 Ok(Self {
2442 kind,
2443 suggestion_id: NesSuggestionId::new(suggestion_id),
2444 fields,
2445 })
2446 }
2447}
2448
2449fn is_known_nes_suggestion_kind(kind: &str) -> bool {
2450 matches!(kind, "edit" | "jump" | "rename" | "searchAndReplace")
2451}
2452
2453fn other_nes_suggestion_schema(schema: &mut Schema) {
2454 super::schema_util::reject_known_string_discriminators(
2455 schema,
2456 "kind",
2457 &["edit", "jump", "rename", "searchAndReplace"],
2458 );
2459}
2460
2461#[serde_as]
2463#[skip_serializing_none]
2464#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2465#[serde(rename_all = "camelCase")]
2466#[non_exhaustive]
2467pub struct NesEditSuggestion {
2468 pub suggestion_id: NesSuggestionId,
2470 #[schemars(url)]
2472 pub uri: String,
2473 #[schemars(length(min = 1))]
2475 pub edits: Vec<NesTextEdit>,
2476 #[serde_as(deserialize_as = "DefaultOnError")]
2478 #[schemars(extend("x-deserialize-default-on-error" = true))]
2479 #[serde(default)]
2480 pub cursor_position: Option<Position>,
2481 #[serde_as(deserialize_as = "DefaultOnError")]
2487 #[schemars(extend("x-deserialize-default-on-error" = true))]
2488 #[serde(default)]
2489 #[serde(rename = "_meta")]
2490 pub meta: Option<Meta>,
2491}
2492
2493impl NesEditSuggestion {
2494 #[must_use]
2496 pub fn new(
2497 suggestion_id: impl Into<NesSuggestionId>,
2498 uri: impl Into<String>,
2499 edits: Vec<NesTextEdit>,
2500 ) -> Self {
2501 Self {
2502 suggestion_id: suggestion_id.into(),
2503 uri: uri.into(),
2504 edits,
2505 cursor_position: None,
2506 meta: None,
2507 }
2508 }
2509
2510 #[must_use]
2512 pub fn cursor_position(mut self, cursor_position: impl IntoOption<Position>) -> Self {
2513 self.cursor_position = cursor_position.into_option();
2514 self
2515 }
2516
2517 #[must_use]
2523 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2524 self.meta = meta.into_option();
2525 self
2526 }
2527}
2528
2529#[serde_as]
2531#[skip_serializing_none]
2532#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2533#[serde(rename_all = "camelCase")]
2534#[non_exhaustive]
2535pub struct NesTextEdit {
2536 pub range: Range,
2538 pub new_text: String,
2540 #[serde_as(deserialize_as = "DefaultOnError")]
2546 #[schemars(extend("x-deserialize-default-on-error" = true))]
2547 #[serde(default)]
2548 #[serde(rename = "_meta")]
2549 pub meta: Option<Meta>,
2550}
2551
2552impl NesTextEdit {
2553 #[must_use]
2555 pub fn new(range: Range, new_text: impl Into<String>) -> Self {
2556 Self {
2557 range,
2558 new_text: new_text.into(),
2559 meta: None,
2560 }
2561 }
2562
2563 #[must_use]
2569 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2570 self.meta = meta.into_option();
2571 self
2572 }
2573}
2574
2575#[serde_as]
2577#[skip_serializing_none]
2578#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2579#[serde(rename_all = "camelCase")]
2580#[non_exhaustive]
2581pub struct NesJumpSuggestion {
2582 pub suggestion_id: NesSuggestionId,
2584 #[schemars(url)]
2586 pub uri: String,
2587 pub position: Position,
2589 #[serde_as(deserialize_as = "DefaultOnError")]
2595 #[schemars(extend("x-deserialize-default-on-error" = true))]
2596 #[serde(default)]
2597 #[serde(rename = "_meta")]
2598 pub meta: Option<Meta>,
2599}
2600
2601impl NesJumpSuggestion {
2602 #[must_use]
2604 pub fn new(
2605 suggestion_id: impl Into<NesSuggestionId>,
2606 uri: impl Into<String>,
2607 position: Position,
2608 ) -> Self {
2609 Self {
2610 suggestion_id: suggestion_id.into(),
2611 uri: uri.into(),
2612 position,
2613 meta: None,
2614 }
2615 }
2616
2617 #[must_use]
2623 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2624 self.meta = meta.into_option();
2625 self
2626 }
2627}
2628
2629#[serde_as]
2631#[skip_serializing_none]
2632#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2633#[serde(rename_all = "camelCase")]
2634#[non_exhaustive]
2635pub struct NesRenameSuggestion {
2636 pub suggestion_id: NesSuggestionId,
2638 #[schemars(url)]
2640 pub uri: String,
2641 pub position: Position,
2643 pub new_name: String,
2645 #[serde_as(deserialize_as = "DefaultOnError")]
2651 #[schemars(extend("x-deserialize-default-on-error" = true))]
2652 #[serde(default)]
2653 #[serde(rename = "_meta")]
2654 pub meta: Option<Meta>,
2655}
2656
2657impl NesRenameSuggestion {
2658 #[must_use]
2660 pub fn new(
2661 suggestion_id: impl Into<NesSuggestionId>,
2662 uri: impl Into<String>,
2663 position: Position,
2664 new_name: impl Into<String>,
2665 ) -> Self {
2666 Self {
2667 suggestion_id: suggestion_id.into(),
2668 uri: uri.into(),
2669 position,
2670 new_name: new_name.into(),
2671 meta: None,
2672 }
2673 }
2674
2675 #[must_use]
2681 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2682 self.meta = meta.into_option();
2683 self
2684 }
2685}
2686
2687#[serde_as]
2689#[skip_serializing_none]
2690#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2691#[serde(rename_all = "camelCase")]
2692#[non_exhaustive]
2693pub struct NesSearchAndReplaceSuggestion {
2694 pub suggestion_id: NesSuggestionId,
2696 #[schemars(url)]
2698 pub uri: String,
2699 pub search: String,
2701 pub replace: String,
2703 #[serde(default)]
2705 pub is_regex: Option<bool>,
2706 #[serde_as(deserialize_as = "DefaultOnError")]
2712 #[schemars(extend("x-deserialize-default-on-error" = true))]
2713 #[serde(default)]
2714 #[serde(rename = "_meta")]
2715 pub meta: Option<Meta>,
2716}
2717
2718impl NesSearchAndReplaceSuggestion {
2719 #[must_use]
2721 pub fn new(
2722 suggestion_id: impl Into<NesSuggestionId>,
2723 uri: impl Into<String>,
2724 search: impl Into<String>,
2725 replace: impl Into<String>,
2726 ) -> Self {
2727 Self {
2728 suggestion_id: suggestion_id.into(),
2729 uri: uri.into(),
2730 search: search.into(),
2731 replace: replace.into(),
2732 is_regex: None,
2733 meta: None,
2734 }
2735 }
2736
2737 #[must_use]
2739 pub fn is_regex(mut self, is_regex: impl IntoOption<bool>) -> Self {
2740 self.is_regex = is_regex.into_option();
2741 self
2742 }
2743
2744 #[must_use]
2750 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2751 self.meta = meta.into_option();
2752 self
2753 }
2754}
2755
2756#[serde_as]
2760#[skip_serializing_none]
2761#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2762#[schemars(extend("x-side" = "agent", "x-method" = NES_ACCEPT_METHOD_NAME))]
2763#[serde(rename_all = "camelCase")]
2764#[non_exhaustive]
2765pub struct AcceptNesNotification {
2766 pub session_id: SessionId,
2768 pub suggestion_id: NesSuggestionId,
2770 #[serde_as(deserialize_as = "DefaultOnError")]
2776 #[schemars(extend("x-deserialize-default-on-error" = true))]
2777 #[serde(default)]
2778 #[serde(rename = "_meta")]
2779 pub meta: Option<Meta>,
2780}
2781
2782impl AcceptNesNotification {
2783 #[must_use]
2785 pub fn new(
2786 session_id: impl Into<SessionId>,
2787 suggestion_id: impl Into<NesSuggestionId>,
2788 ) -> Self {
2789 Self {
2790 session_id: session_id.into(),
2791 suggestion_id: suggestion_id.into(),
2792 meta: None,
2793 }
2794 }
2795
2796 #[must_use]
2802 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2803 self.meta = meta.into_option();
2804 self
2805 }
2806}
2807
2808#[serde_as]
2810#[skip_serializing_none]
2811#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2812#[schemars(extend("x-side" = "agent", "x-method" = NES_REJECT_METHOD_NAME))]
2813#[serde(rename_all = "camelCase")]
2814#[non_exhaustive]
2815pub struct RejectNesNotification {
2816 pub session_id: SessionId,
2818 pub suggestion_id: NesSuggestionId,
2820 #[serde_as(deserialize_as = "DefaultOnError")]
2822 #[schemars(extend("x-deserialize-default-on-error" = true))]
2823 #[serde(default)]
2824 pub reason: Option<NesRejectReason>,
2825 #[serde_as(deserialize_as = "DefaultOnError")]
2831 #[schemars(extend("x-deserialize-default-on-error" = true))]
2832 #[serde(default)]
2833 #[serde(rename = "_meta")]
2834 pub meta: Option<Meta>,
2835}
2836
2837impl RejectNesNotification {
2838 #[must_use]
2840 pub fn new(
2841 session_id: impl Into<SessionId>,
2842 suggestion_id: impl Into<NesSuggestionId>,
2843 ) -> Self {
2844 Self {
2845 session_id: session_id.into(),
2846 suggestion_id: suggestion_id.into(),
2847 reason: None,
2848 meta: None,
2849 }
2850 }
2851
2852 #[must_use]
2854 pub fn reason(mut self, reason: impl IntoOption<NesRejectReason>) -> Self {
2855 self.reason = reason.into_option();
2856 self
2857 }
2858
2859 #[must_use]
2865 pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2866 self.meta = meta.into_option();
2867 self
2868 }
2869}
2870
2871#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2873#[non_exhaustive]
2874pub enum NesRejectReason {
2875 #[serde(rename = "rejected")]
2877 Rejected,
2878 #[serde(rename = "ignored")]
2880 Ignored,
2881 #[serde(rename = "replaced")]
2883 Replaced,
2884 #[serde(rename = "cancelled")]
2886 Cancelled,
2887 #[serde(untagged)]
2893 Other(String),
2894}
2895
2896#[cfg(test)]
2897mod tests {
2898 use super::*;
2899 use serde_json::json;
2900
2901 #[test]
2902 fn test_position_encoding_kind_serialization() {
2903 assert_eq!(
2904 serde_json::to_value(&PositionEncodingKind::Utf16).unwrap(),
2905 json!("utf-16")
2906 );
2907 assert_eq!(
2908 serde_json::to_value(&PositionEncodingKind::Utf32).unwrap(),
2909 json!("utf-32")
2910 );
2911 assert_eq!(
2912 serde_json::to_value(&PositionEncodingKind::Utf8).unwrap(),
2913 json!("utf-8")
2914 );
2915
2916 assert_eq!(
2917 serde_json::from_value::<PositionEncodingKind>(json!("utf-16")).unwrap(),
2918 PositionEncodingKind::Utf16
2919 );
2920 assert_eq!(
2921 serde_json::from_value::<PositionEncodingKind>(json!("utf-32")).unwrap(),
2922 PositionEncodingKind::Utf32
2923 );
2924 assert_eq!(
2925 serde_json::from_value::<PositionEncodingKind>(json!("utf-8")).unwrap(),
2926 PositionEncodingKind::Utf8
2927 );
2928 assert!(serde_json::from_value::<PositionEncodingKind>(json!("_future")).is_err());
2929 }
2930
2931 #[test]
2932 fn test_client_capabilities_skip_unknown_position_encodings() {
2933 let caps: crate::v2::ClientCapabilities = serde_json::from_value(json!({
2934 "positionEncodings": ["_future", "utf-8", "utf-16"]
2935 }))
2936 .unwrap();
2937
2938 assert_eq!(
2939 caps.position_encodings,
2940 vec![PositionEncodingKind::Utf8, PositionEncodingKind::Utf16]
2941 );
2942 }
2943
2944 #[test]
2945 fn test_agent_nes_capabilities_serialization() {
2946 let caps = NesCapabilities::new()
2947 .events(
2948 NesEventCapabilities::new().document(
2949 NesDocumentEventCapabilities::new()
2950 .did_open(NesDocumentDidOpenCapabilities::default())
2951 .did_change(NesDocumentDidChangeCapabilities::new(
2952 TextDocumentSyncKind::Incremental,
2953 ))
2954 .did_close(NesDocumentDidCloseCapabilities::default())
2955 .did_save(NesDocumentDidSaveCapabilities::default())
2956 .did_focus(NesDocumentDidFocusCapabilities::default()),
2957 ),
2958 )
2959 .context(
2960 NesContextCapabilities::new()
2961 .recent_files(NesRecentFilesCapabilities {
2962 max_count: Some(10),
2963 meta: None,
2964 })
2965 .related_snippets(NesRelatedSnippetsCapabilities::default())
2966 .edit_history(NesEditHistoryCapabilities {
2967 max_count: Some(6),
2968 meta: None,
2969 })
2970 .user_actions(NesUserActionsCapabilities {
2971 max_count: Some(16),
2972 meta: None,
2973 })
2974 .open_files(NesOpenFilesCapabilities::default())
2975 .diagnostics(NesDiagnosticsCapabilities::default()),
2976 );
2977
2978 let json = serde_json::to_value(&caps).unwrap();
2979 assert_eq!(
2980 json,
2981 json!({
2982 "events": {
2983 "document": {
2984 "didOpen": {},
2985 "didChange": {
2986 "syncKind": "incremental"
2987 },
2988 "didClose": {},
2989 "didSave": {},
2990 "didFocus": {}
2991 }
2992 },
2993 "context": {
2994 "recentFiles": {
2995 "maxCount": 10
2996 },
2997 "relatedSnippets": {},
2998 "editHistory": {
2999 "maxCount": 6
3000 },
3001 "userActions": {
3002 "maxCount": 16
3003 },
3004 "openFiles": {},
3005 "diagnostics": {}
3006 }
3007 })
3008 );
3009
3010 let deserialized: NesCapabilities = serde_json::from_value(json).unwrap();
3012 assert_eq!(deserialized, caps);
3013 }
3014
3015 #[test]
3016 fn test_client_nes_capabilities_serialization() {
3017 let caps = ClientNesCapabilities::new()
3018 .jump(NesJumpCapabilities::default())
3019 .rename(NesRenameCapabilities::default())
3020 .search_and_replace(NesSearchAndReplaceCapabilities::default());
3021
3022 let json = serde_json::to_value(&caps).unwrap();
3023 assert_eq!(
3024 json,
3025 json!({
3026 "jump": {},
3027 "rename": {},
3028 "searchAndReplace": {}
3029 })
3030 );
3031
3032 let deserialized: ClientNesCapabilities = serde_json::from_value(json).unwrap();
3033 assert_eq!(deserialized, caps);
3034 }
3035
3036 #[test]
3037 fn test_document_did_open_serialization() {
3038 let notification = DidOpenDocumentNotification::new(
3039 "session_123",
3040 "file:///path/to/file.rs",
3041 "rust",
3042 1,
3043 "fn main() {\n println!(\"hello\");\n}\n",
3044 );
3045
3046 let json = serde_json::to_value(¬ification).unwrap();
3047 assert_eq!(
3048 json,
3049 json!({
3050 "sessionId": "session_123",
3051 "uri": "file:///path/to/file.rs",
3052 "languageId": "rust",
3053 "version": 1,
3054 "text": "fn main() {\n println!(\"hello\");\n}\n"
3055 })
3056 );
3057
3058 let deserialized: DidOpenDocumentNotification = serde_json::from_value(json).unwrap();
3059 assert_eq!(deserialized, notification);
3060 }
3061
3062 #[test]
3063 fn test_document_did_change_incremental_serialization() {
3064 let notification = DidChangeDocumentNotification::new(
3065 "session_123",
3066 "file:///path/to/file.rs",
3067 2,
3068 vec![TextDocumentContentChangeEvent::incremental(
3069 Range::new(Position::new(1, 4), Position::new(1, 4)),
3070 "let x = 42;\n ",
3071 )],
3072 );
3073
3074 let json = serde_json::to_value(¬ification).unwrap();
3075 assert_eq!(
3076 json,
3077 json!({
3078 "sessionId": "session_123",
3079 "uri": "file:///path/to/file.rs",
3080 "version": 2,
3081 "contentChanges": [
3082 {
3083 "range": {
3084 "start": { "line": 1, "character": 4 },
3085 "end": { "line": 1, "character": 4 }
3086 },
3087 "text": "let x = 42;\n "
3088 }
3089 ]
3090 })
3091 );
3092 }
3093
3094 #[test]
3095 fn test_document_did_change_full_serialization() {
3096 let notification = DidChangeDocumentNotification::new(
3097 "session_123",
3098 "file:///path/to/file.rs",
3099 2,
3100 vec![TextDocumentContentChangeEvent::full(
3101 "fn main() {\n let x = 42;\n println!(\"hello\");\n}\n",
3102 )],
3103 );
3104
3105 let json = serde_json::to_value(¬ification).unwrap();
3106 assert_eq!(
3107 json,
3108 json!({
3109 "sessionId": "session_123",
3110 "uri": "file:///path/to/file.rs",
3111 "version": 2,
3112 "contentChanges": [
3113 {
3114 "text": "fn main() {\n let x = 42;\n println!(\"hello\");\n}\n"
3115 }
3116 ]
3117 })
3118 );
3119 }
3120
3121 #[test]
3122 fn test_document_did_close_serialization() {
3123 let notification =
3124 DidCloseDocumentNotification::new("session_123", "file:///path/to/file.rs");
3125 let json = serde_json::to_value(¬ification).unwrap();
3126 assert_eq!(
3127 json,
3128 json!({ "sessionId": "session_123", "uri": "file:///path/to/file.rs" })
3129 );
3130 }
3131
3132 #[test]
3133 fn test_document_did_save_serialization() {
3134 let notification =
3135 DidSaveDocumentNotification::new("session_123", "file:///path/to/file.rs");
3136 let json = serde_json::to_value(¬ification).unwrap();
3137 assert_eq!(
3138 json,
3139 json!({ "sessionId": "session_123", "uri": "file:///path/to/file.rs" })
3140 );
3141 }
3142
3143 #[test]
3144 fn test_document_did_focus_serialization() {
3145 let notification = DidFocusDocumentNotification::new(
3146 "session_123",
3147 "file:///path/to/file.rs",
3148 2,
3149 Position::new(5, 12),
3150 Range::new(Position::new(0, 0), Position::new(45, 0)),
3151 );
3152
3153 let json = serde_json::to_value(¬ification).unwrap();
3154 assert_eq!(
3155 json,
3156 json!({
3157 "sessionId": "session_123",
3158 "uri": "file:///path/to/file.rs",
3159 "version": 2,
3160 "position": { "line": 5, "character": 12 },
3161 "visibleRange": {
3162 "start": { "line": 0, "character": 0 },
3163 "end": { "line": 45, "character": 0 }
3164 }
3165 })
3166 );
3167 }
3168
3169 #[test]
3170 fn test_nes_suggestion_edit_serialization() {
3171 let suggestion = NesSuggestion::Edit(
3172 NesEditSuggestion::new(
3173 "sugg_001",
3174 "file:///path/to/other_file.rs",
3175 vec![NesTextEdit::new(
3176 Range::new(Position::new(5, 0), Position::new(5, 10)),
3177 "let result = helper();",
3178 )],
3179 )
3180 .cursor_position(Position::new(5, 22)),
3181 );
3182
3183 let json = serde_json::to_value(&suggestion).unwrap();
3184 assert_eq!(
3185 json,
3186 json!({
3187 "kind": "edit",
3188 "suggestionId": "sugg_001",
3189 "uri": "file:///path/to/other_file.rs",
3190 "edits": [
3191 {
3192 "range": {
3193 "start": { "line": 5, "character": 0 },
3194 "end": { "line": 5, "character": 10 }
3195 },
3196 "newText": "let result = helper();"
3197 }
3198 ],
3199 "cursorPosition": { "line": 5, "character": 22 }
3200 })
3201 );
3202
3203 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
3204 assert_eq!(deserialized, suggestion);
3205 }
3206
3207 #[test]
3208 fn test_nes_suggestion_unknown_variant() {
3209 let suggestion: NesSuggestion = serde_json::from_value(json!({
3210 "kind": "_preview",
3211 "suggestionId": "sugg_001",
3212 "label": "Preview generated file"
3213 }))
3214 .unwrap();
3215
3216 let NesSuggestion::Other(unknown) = suggestion else {
3217 panic!("expected unknown NES suggestion");
3218 };
3219
3220 assert_eq!(unknown.kind, "_preview");
3221 assert_eq!(unknown.suggestion_id.to_string(), "sugg_001");
3222 assert!(!unknown.fields.contains_key("suggestionId"));
3223 assert_eq!(
3224 serde_json::to_value(NesSuggestion::Other(unknown)).unwrap(),
3225 json!({
3226 "kind": "_preview",
3227 "suggestionId": "sugg_001",
3228 "label": "Preview generated file"
3229 })
3230 );
3231 }
3232
3233 #[test]
3234 fn test_nes_suggestion_unknown_does_not_hide_malformed_known_variant() {
3235 assert!(
3236 serde_json::from_value::<NesSuggestion>(json!({
3237 "kind": "edit"
3238 }))
3239 .is_err()
3240 );
3241 }
3242
3243 #[test]
3244 fn test_nes_suggestion_jump_serialization() {
3245 let suggestion = NesSuggestion::Jump(NesJumpSuggestion::new(
3246 "sugg_002",
3247 "file:///path/to/other_file.rs",
3248 Position::new(15, 4),
3249 ));
3250
3251 let json = serde_json::to_value(&suggestion).unwrap();
3252 assert_eq!(
3253 json,
3254 json!({
3255 "kind": "jump",
3256 "suggestionId": "sugg_002",
3257 "uri": "file:///path/to/other_file.rs",
3258 "position": { "line": 15, "character": 4 }
3259 })
3260 );
3261
3262 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
3263 assert_eq!(deserialized, suggestion);
3264 }
3265
3266 #[test]
3267 fn test_nes_suggestion_rename_serialization() {
3268 let suggestion = NesSuggestion::Rename(NesRenameSuggestion::new(
3269 "sugg_003",
3270 "file:///path/to/file.rs",
3271 Position::new(5, 10),
3272 "calculateTotal",
3273 ));
3274
3275 let json = serde_json::to_value(&suggestion).unwrap();
3276 assert_eq!(
3277 json,
3278 json!({
3279 "kind": "rename",
3280 "suggestionId": "sugg_003",
3281 "uri": "file:///path/to/file.rs",
3282 "position": { "line": 5, "character": 10 },
3283 "newName": "calculateTotal"
3284 })
3285 );
3286
3287 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
3288 assert_eq!(deserialized, suggestion);
3289 }
3290
3291 #[test]
3292 fn test_nes_suggestion_search_and_replace_serialization() {
3293 let suggestion = NesSuggestion::SearchAndReplace(
3294 NesSearchAndReplaceSuggestion::new(
3295 "sugg_004",
3296 "file:///path/to/file.rs",
3297 "oldFunction",
3298 "newFunction",
3299 )
3300 .is_regex(false),
3301 );
3302
3303 let json = serde_json::to_value(&suggestion).unwrap();
3304 assert_eq!(
3305 json,
3306 json!({
3307 "kind": "searchAndReplace",
3308 "suggestionId": "sugg_004",
3309 "uri": "file:///path/to/file.rs",
3310 "search": "oldFunction",
3311 "replace": "newFunction",
3312 "isRegex": false
3313 })
3314 );
3315
3316 let deserialized: NesSuggestion = serde_json::from_value(json).unwrap();
3317 assert_eq!(deserialized, suggestion);
3318 }
3319
3320 #[test]
3321 fn test_nes_start_request_serialization() {
3322 let request = StartNesRequest::new()
3323 .workspace_uri("file:///Users/alice/projects/my-app")
3324 .workspace_folders(vec![WorkspaceFolder::new(
3325 "file:///Users/alice/projects/my-app",
3326 "my-app",
3327 )])
3328 .repository(NesRepository::new(
3329 "my-app",
3330 "alice",
3331 "https://github.com/alice/my-app.git",
3332 ));
3333
3334 let json = serde_json::to_value(&request).unwrap();
3335 assert_eq!(
3336 json,
3337 json!({
3338 "workspaceUri": "file:///Users/alice/projects/my-app",
3339 "workspaceFolders": [
3340 {
3341 "uri": "file:///Users/alice/projects/my-app",
3342 "name": "my-app"
3343 }
3344 ],
3345 "repository": {
3346 "name": "my-app",
3347 "owner": "alice",
3348 "remoteUrl": "https://github.com/alice/my-app.git"
3349 }
3350 })
3351 );
3352 }
3353
3354 #[test]
3355 fn test_nes_start_response_serialization() {
3356 let response = StartNesResponse::new("session_abc123");
3357 let json = serde_json::to_value(&response).unwrap();
3358 assert_eq!(json, json!({ "sessionId": "session_abc123" }));
3359 }
3360
3361 #[test]
3362 fn test_nes_trigger_kind_serialization() {
3363 assert_eq!(
3364 serde_json::to_value(&NesTriggerKind::Automatic).unwrap(),
3365 json!("automatic")
3366 );
3367 assert_eq!(
3368 serde_json::to_value(&NesTriggerKind::Diagnostic).unwrap(),
3369 json!("diagnostic")
3370 );
3371 assert_eq!(
3372 serde_json::to_value(&NesTriggerKind::Manual).unwrap(),
3373 json!("manual")
3374 );
3375 }
3376
3377 #[test]
3378 fn test_nes_reject_reason_serialization() {
3379 assert_eq!(
3380 serde_json::to_value(&NesRejectReason::Rejected).unwrap(),
3381 json!("rejected")
3382 );
3383 assert_eq!(
3384 serde_json::to_value(&NesRejectReason::Ignored).unwrap(),
3385 json!("ignored")
3386 );
3387 assert_eq!(
3388 serde_json::to_value(&NesRejectReason::Replaced).unwrap(),
3389 json!("replaced")
3390 );
3391 assert_eq!(
3392 serde_json::to_value(&NesRejectReason::Cancelled).unwrap(),
3393 json!("cancelled")
3394 );
3395 }
3396
3397 #[test]
3398 fn test_nes_accept_notification_serialization() {
3399 let notification = AcceptNesNotification::new("session_123", "sugg_001");
3400 let json = serde_json::to_value(¬ification).unwrap();
3401 assert_eq!(
3402 json,
3403 json!({ "sessionId": "session_123", "suggestionId": "sugg_001" })
3404 );
3405 }
3406
3407 #[test]
3408 fn test_nes_reject_notification_serialization() {
3409 let notification =
3410 RejectNesNotification::new("session_123", "sugg_001").reason(NesRejectReason::Rejected);
3411 let json = serde_json::to_value(¬ification).unwrap();
3412 assert_eq!(
3413 json,
3414 json!({ "sessionId": "session_123", "suggestionId": "sugg_001", "reason": "rejected" })
3415 );
3416 }
3417
3418 #[test]
3419 fn test_nes_suggest_request_with_context_serialization() {
3420 let request = SuggestNesRequest::new(
3421 "session_123",
3422 "file:///path/to/file.rs",
3423 2,
3424 Position::new(5, 12),
3425 NesTriggerKind::Automatic,
3426 )
3427 .selection(Range::new(Position::new(5, 4), Position::new(5, 12)))
3428 .context(
3429 NesSuggestContext::new()
3430 .recent_files(vec![NesRecentFile::new(
3431 "file:///path/to/utils.rs",
3432 "rust",
3433 "pub fn helper() -> i32 { 42 }\n",
3434 )])
3435 .diagnostics(vec![NesDiagnostic::new(
3436 "file:///path/to/file.rs",
3437 Range::new(Position::new(5, 0), Position::new(5, 10)),
3438 NesDiagnosticSeverity::Error,
3439 "cannot find value `foo` in this scope",
3440 )]),
3441 );
3442
3443 let json = serde_json::to_value(&request).unwrap();
3444 assert_eq!(json["sessionId"], "session_123");
3445 assert_eq!(json["uri"], "file:///path/to/file.rs");
3446 assert_eq!(json["version"], 2);
3447 assert_eq!(json["triggerKind"], "automatic");
3448 assert_eq!(
3449 json["context"]["recentFiles"][0]["uri"],
3450 "file:///path/to/utils.rs"
3451 );
3452 assert_eq!(json["context"]["diagnostics"][0]["severity"], "error");
3453 }
3454
3455 #[test]
3456 fn test_text_document_sync_kind_serialization() {
3457 assert_eq!(
3458 serde_json::to_value(&TextDocumentSyncKind::Full).unwrap(),
3459 json!("full")
3460 );
3461 assert_eq!(
3462 serde_json::to_value(&TextDocumentSyncKind::Incremental).unwrap(),
3463 json!("incremental")
3464 );
3465 assert!(serde_json::from_value::<TextDocumentSyncKind>(json!("_future")).is_err());
3466 }
3467
3468 #[test]
3469 fn test_document_event_capabilities_drop_unknown_did_change_sync_kind() {
3470 let caps: NesDocumentEventCapabilities = serde_json::from_value(json!({
3471 "didChange": {
3472 "syncKind": "_future"
3473 }
3474 }))
3475 .unwrap();
3476
3477 assert_eq!(caps.did_change, None);
3478 }
3479
3480 #[test]
3481 fn test_document_did_change_capabilities_requires_sync_kind() {
3482 assert!(serde_json::from_value::<NesDocumentDidChangeCapabilities>(json!({})).is_err());
3483 }
3484
3485 #[test]
3486 fn test_nes_suggest_response_serialization() {
3487 let response = SuggestNesResponse::new(vec![
3488 NesSuggestion::Edit(NesEditSuggestion::new(
3489 "sugg_001",
3490 "file:///path/to/file.rs",
3491 vec![NesTextEdit::new(
3492 Range::new(Position::new(5, 0), Position::new(5, 10)),
3493 "let result = helper();",
3494 )],
3495 )),
3496 NesSuggestion::Jump(NesJumpSuggestion::new(
3497 "sugg_002",
3498 "file:///path/to/other.rs",
3499 Position::new(10, 0),
3500 )),
3501 ]);
3502
3503 let json = serde_json::to_value(&response).unwrap();
3504 assert_eq!(json["suggestions"].as_array().unwrap().len(), 2);
3505 assert_eq!(json["suggestions"][0]["kind"], "edit");
3506 assert_eq!(json["suggestions"][1]["kind"], "jump");
3507 }
3508}